パイプ インターフェースには、バッチ処理および直接のコマンド呼び出しという長所があります。 バッチ オプションと同様に、CLI とマネージャ間でのセッション中に複数のコマンドを実行することができます。 ただし、スクリプトはそのコマンドの出力結果を次の CLI コマンドを開始する前に処理することが可能です。 パイプ キーワードは、パイプの名前が後に続くパイプ インターフェースをアクティブ化します。 このパイプは、Windows では名前付きパイプ、Linux では fifo ファイルです。 いずれの場合も、CLI はパイプ クライアントとして動作します。 呼び出し元のスクリプトでパイプを作成および管理します。 CLI は、パイプ インターフェースを処理するために呼び出されると、クレデンシャルを使用してマネージャへの接続を確立し、その結果を stdout に記録します。 セッションが確立されると、何らかのコマンドの処理に備え、CLI によるパイプのリスニングが行われます。 コマンドを受け取ると、そのコマンドを処理し、結果を stdout に記録します。 処理が終わると、再び次のコマンドに対するリスニングを開始します。 バッチ モードと異なって、パイプ モードでの CLI は、コマンドが正常に処理されたかどうかにかかわらず、常にパイプに戻ります。 コマンドが失敗した場合でも、CLI とマネージャ間のセッションは終了しません。 この動作は、バッチ モードで SDCMD_CONTINUE=ON を指定した場合に相当します。
CLI と起動したスクリプトとの間の通信および同期を容易にするために、CLI には、CLI の処理が終了したこと、および CLI が再びパイプのリスニングを開始したことを示すいくつかのアイ キャッチャが用意されています。
パイプ モードの CLI を起動すると、CLI が stdout に以下のメッセージを出力します。
*** SDCMD: Line up ***
CLI がパイプをリスンし始める場合、スクリプトは CLI にパイプを介してコマンドを送信し始めることができます。 コマンド処理の終了も、特殊なアイ キャッチャによってレポートされます。 コマンドが終了すると、正常に終了したかどうかに関係なく、常に CLI が stdout に以下のメッセージを出力します。
### SDCMD: -eoc ###
スクリプトは、この文字列を検出すると、自身の起動したコマンドが終了し、コマンド出力がすべて stdout に書き込まれたことを認識します。
アプリケーションからパイプ経由で送信されるコマンドは、バッチ ファイルと同じ形式のものになります。 アプリケーションによってパイプに書き込まれるコマンド バッファには、実行対象のコマンドが完全な形で存在している必要があります。 1 つのコマンドを複数の送信バッファに配信することはできません。
複数のコマンドを 1 つのバッファに送信することは可能です。 以下の文字列によってコマンドを区切ります。
-eoc
CLI が以下の文字列をパイプ経由で受け取ると、
-quit
ただちにパイプ モードの CLI とマネージャ間のセッションが終了します。
「pipe」キーワードに続けて、CLI が処理対象のコマンドを受け取るために使用するパイプ名をコーディングすると、CLI がパイプ インターフェースに対して呼び出されます。 キーワードとパイプ名との間には、1 つ以上の空白が必要です。
以下の例は、Linux でのパイプ インターフェースの使用法を示したものです。 このスクリプトを実行すると、USD に登録されているターゲット コンピュータおよび USD ソフトウェア ライブラリに登録されている製品が一覧表示されます。
#! /usr/bin/sh
proto ()
{
aa=" "
bb=`echo "$aa" | grep "SDCMD: Line up"`
while [ -z "$bb" ]
do
read aa
bb=`echo "$aa" | grep "SDCMD: Line up"`
if [ -z "$bb" ]
then
echo "$aa"
fi
done
}
prot ()
{
aa=" "
bb=`echo "$aa" | grep "SDCMD: -eoc"`
while [ -z "$bb" ]
do
read aa
bb=`echo "$aa" | grep "SDCMD: -eoc"`
if [ -z "$bb" ]
then
echo "$aa"
fi
done
}
mkfifo /ca_dsmcmd_in
mkfifo /ca_dsmcmd_out
{
cadsmcmd pipe /ca_dsmcmd_in > /ca_dsmcmd_out &
proto
echo "targetComputer action=list -eoc" > /ca_dsmcmd_in
prot
#
# store returned list and process it
#
# ...
#
# next command
echo "swLibrary action=list -eoc" > /ca_dsmcmd_in
prot
#
# store returned list and process it
#
# ...
#
# terminate session
echo "-quit" > /ca_dsmcmd_in
} < /ca_dsmcmd_out
rm /ca_dsmcmd_*
この例は、2 つのルーチンとメインライン部で構成されています。 ルーチン「proto ()」はパイプ インターフェースが開始されコマンドの待機中であることを示す「### SDCMD: Line up ###」に対してトリガされ、ルーチン「prot ()」はコマンドの処理が完了したことを示す「### SDCMD: -eoc ###」に対してトリガされます。
メインライン部では、まずパイプが 2 つ作成されます。 CLI は、入力パイプとしてパイプ「/ca_dsmcmd_in」を使用し、このパイプを介して処理対象のコマンドを受け取ります。 もう 1 つのパイプ「/ca_dsmcmd_out」は、スクリプトが出力結果を処理できるよう、CLI の stdout をスクリプトにリダイレクトするために使用されます。 これらのパイプが作成された後、パイプ モードの CLI をバッチで起動するブロックが開始され、targetComputer および swLibrary に対してそれぞれ list コマンドが実行されます。これが完了すると、セッションが終了します。 このブロックは、「/ca_dsmcmd_out」パイプから入力を受け取り、CLI の出力を記録します。 「/ca_dsmcmd_out」パイプは、CLI の存続時間中スクリプトのために常に開いたままにしておいてください。 たとえば、「/ca_dsmcmd_out」パイプを proto ルーチンおよび prot ルーチンへの入力としてのみ割り当てた場合には、実行時にデータの損失を伴う問題が発生し、セッションがハングアップすることがあります。
パイプ モードの CLI がバッチで起動された後、CLI をトリガして機能可能な状態にするため proto ルーチンが使用されます。 スクリプトは制御が戻ると、targetComputer に対するリスト アクションを起動し、prot ルーチンを使用してコマンド処理の終了を判断します。 この prot ルーチンの出力は、後続のスクリプト処理で利用できるよう、ファイルにリダイレクトすることもできます。 次に、swLibrary に対するリスト アクションが起動し、コマンド処理の終了を判断するために再び prot ルーチンが使用されます。 この prot ルーチンの出力も、後続のスクリプト処理で利用できるよう、ファイルにリダイレクトすることができます。 最後に、-quit で CLI をシャットダウンしてこのブロックが終了します。
スクリプトの最終行は、パイプをハウスキーピングおよびクリーン アップするためのものです。
以下の例は、前述の例と同じ作業を実行するものですが、DM Scripting を使用しており、Windows 向けの内容になっています。
Dim hPipeIn, hPipeOut As Integer
Dim pipeIn, pipeOut As String
Dim command_1, command_2, eoc, eop, lineUp, endOfCommand, buffer As String
' ************************************************************************
' clear screen
ClrScr()
' ************************************************************************
' set constants
eoc = " -eoc"
eop = "-quit"
command_1 = "targetComputer action=list" + eoc
command_2 = "swLibrary action=list" + eoc
lineUp = "SDCMD: Line up"
endOfCommand = "SDCMD: -eoc"
pipeIn ="\\.\pipe\ca_dsmcmd_in"
pipeOut ="\\.\pipe\ca_dsmcmd_out"
' ************************************************************************
' Create input pipe of CLI
hPipeIn = CreatePipe(pipeIn, O_WRITE)
If (hPipeIn = -1) Then
MsgBox("Open pipe """ + pipeIn + """ failed.", "Pipe test", MB_OK + MB_ICONSTOP + MB_SETFOREGROUND)
exit
EndIf
' ************************************************************************
' Create output pipe of CLI
hPipeOut = CreatePipe(pipeOut, O_READ)
If (hPipeOut = -1) Then
MsgBox("Open pipe """ + pipeOut + """ failed.", "Pipe test", MB_OK + MB_ICONSTOP + MB_SETFOREGROUND)
CloseFile(hPipeIn)
exit
EndIf
' ************************************************************************
' Launch cadsmcmd in pipe mode using pipeIn as input pipe and redirecting
‘ stdout to pipeOut
Execute("cmd /c ""cadsmcmd pipe " + pipeIn + " > " + pipeOut + """", FALSE, 0)
While (TRUE)
If (Not(ReadFile(hPipeOut, buffer))) Then
MsgBox("Read from pipe """ + pipeOut + """ failed.", "Pipe test", MB_OK + MB_ICONSTOP + MB_SETFOREGROUND)
CloseFile(hPipeIn)
CloseFile(hPipeOut)
exit
EndIf
If (InStr(buffer, lineUp) = 0) Then
Print(buffer)
Else
ExitWhile
EndIf
Wend
' ************************************************************************
' launch request for a targetComputer action=list
If (Not(WriteFile(hPipeIn, command_1))) Then
MsgBox("Write to pipe """ + pipeIn + """ failed.", "Pipe test", MB_OK + MB_ICONSTOP + MB_SETFOREGROUND)
CloseFile(hPipeIn)
CloseFile(hPipeOut)
exit
EndIf
While (TRUE)
If (Not(ReadFile(hPipeOut, buffer))) Then
MsgBox("Read from pipe """ + pipeOut + """ failed.", "Pipe test", MB_OK + MB_ICONSTOP + MB_SETFOREGROUND)
CloseFile(hPipeIn)
CloseFile(hPipeOut)
exit
EndIf
If (InStr(buffer, endOfCommand) = 0) Then
' results could be stored for subsequent processing or directly processed.
Print(buffer)
Else
ExitWhile
EndIf
Wend
' ************************************************************************
' launch request for a swLibrary action=list
If (Not(WriteFile(hPipeIn, command_2))) Then
MsgBox("Write to pipe """ + pipeIn + """ failed.", "Pipe test", MB_OK + MB_ICONSTOP + MB_SETFOREGROUND)
CloseFile(hPipeIn)
CloseFile(hPipeOut)
exit
EndIf
While (TRUE)
If (Not(ReadFile(hPipeOut, buffer))) Then
MsgBox("Read from pipe """ + pipeOut + """ failed.", "Pipe test", MB_OK + MB_ICONSTOP + MB_SETFOREGROUND)
CloseFile(hPipeIn)
CloseFile(hPipeOut)
exit
EndIf
If (InStr(buffer, endOfCommand) = 0) Then
' results could be stored for subsequent processing or directly processed.
Print(buffer)
Else
ExitWhile
EndIf
Wend
' ************************************************************************
' terminate CLI
If (Not(WriteFile(hPipeIn, eop))) Then
MsgBox("Write to pipe """ + pipeIn + """ failed.", "Pipe test", MB_OK + MB_ICONSTOP + MB_SETFOREGROUND)
CloseFile(hPipeIn)
CloseFile(hPipeOut)
exit
EndIf
' ************************************************************************
' clean up
CloseFile(hPipeIn)
CloseFile(hPipeOut)
CLI の有効なコマンドはすべて、パイプ インターフェースで利用することができます。
|
Copyright © 2014 CA Technologies.
All rights reserved.
|
|