Previous Topic: batchNext Topic: command


pipe

fThe pipe interface offers the advantage of a batch processing and a direct command invocation. It is possible to run more than one command during a session between the CLI and the manager as with the batch option. But a script has the chance to process the command output before it launches the next CLI command. The pipe keyword activates the pipe interface followed by the name of the pipe. The pipe is a named pipe on Windows while it is a fifo file on Linux. In any case, the CLI works as a pipe client. Created and administer the pipe by the invoking script. When invoked for pipe interface processing, the CLI establishes the connection to the manager with the credentials and records the result to stdout. When the session is established, the CLI listens to the pipe for any command to be processed. When it receives one, the command is processed and its results are recorded at stdout. After the command is processed, the CLI listens again for the next command. Differing from the batch mode, the CLI in pipe mode always returns to the pipe regardless whether a command has been processed successfully or not. The session between CLI and manager is not terminated when a command fails. This behavior corresponds to the batch mode with SDCMD_CONTINUE=ON.

To ease the communication and synchronization between the CLI and the launching script, the CLI provides certain eye catchers that indicate the end of a CLI processing and that the CLI now starts listening to the pipe.

When starting the CLI in pipe mode, the CLI launches the message on stdout

*** SDCMD: Line up ***

When the the CLI starts listening to the pipe, a script can start sending commands via pipe to the CLI. Also, the end of a command processing is reported by a special eye catcher. Whenever a command terminates, successfully or not, the CLI launches the following message on stdout:

### SDCMD: -eoc ###

When a script detects this string, it knows that the command launched by it has been terminated and all command output is written to stdout.

The commands to be sent by an application via pipe are of the same format as in batch files. The command buffer written to the pipe by the application must contain the complete command to be executed. A command cannot be distributed among several send buffers.

You can send more than one command within one buffer. Separate the command by the following string:

-eoc

The session between a CLI in pipe mode and the manager is terminated as soon as the CLI receives the string

-quit

via pipe.

The CLI is invoked for the pipe interface by coding the “pipe” keyword followed by the pipename the CLI uses to receive its commands to be processed. Between the keyword and the pipename have to be at least one blank.

The following example shows the usage of the pipe interface on Linux. The script lists all targetComputers registered at the USD and all products registered at the USD software library.

#! /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_*

The example consists of two routines and the mainline part. The routine “proto ()” triggers for the “### SDCMD: Line up ###” indicating the pipe interface being up and waiting for commands and the routine “prot ()” triggers for “### SDCMD: -eoc ###” indicating processing complete for a command.

The mainline part first creates two pipes. The CLI uses pipe “/ca_dsmcmd_in” as an input pipe, the CLI is receiving the commands to be processed through this pipe. The other pipe “/ca_dsmcmd_out” is used to redirect the stdout of the CLI to the script so that the script might be able to process the results. After these pipes have been created, a block is started that starts the CLI in pipe mode in batch, launches two list commands for targetComputer and swLibrary, and after that terminates the session. This block receives its input from the “/ca_dsmcmd_out” pipe recording the output of the CLI. It is strongly recommended to keep this pipe open for the script during the life time of the CLI. If, for example, this pipe is only assigned as input to the proto and prot procedures, the user might experience run time problems that result in loss of data and might be in hanging sessions.

After the CLI is launched in pipe mode in batch the proto routine is used to trigger for the CLI becoming ready for action. When it returns the script launches the list action for targetComputer and then uses the prot routine to determine the end of command processing. The output of this prot routine could be redirected into a file for subsequent script processing. Then the list action for swLibrary is launched and again the prot routine is used to determine the end of command processing. And again the output of the prot procedure could be redirected into a file for subsequent script processing. Finally the block is terminated by shutting down the CLI per -quit.

The last line of the script is for housekeeping and cleaning up the pipes.

The following example does the same as the example, but it uses DM Scripting and is for 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)

All valid commands of the CLI are available at the pipe interface.