MiniM Knowledge Base | Jun 11, 2010
How to Run External Process and Exchange Data.
There are many integration tasks with needs to run and interact with external processes. MiniM implement special device type |PIPE| to do this.
Device as |PIPE| type is a bidirectional logical input-output channel, which run specified file as child process, specify parameters and make read - write operations througth this virtual interaction channel.
On the MiniM side interaction with child process implemented througth read and write commands. On the child process's side interaction implemented as stdin and stdout standard process's channels.
MiniM run child process using system utility cmd.exe or using utility specified in ComSpec envirunment variable. This methow allow to run external process using executive images as .exe files as such as script files using assisiated file extension handlers, for example .bat, .cmd, .vbs and others, and separate operating system commands, which has not executive image such as dir command for example.
And, also, thia method to run external process allow to use operating system command processor to specify child process's input/output redirection using external files or other processes.
File name tu run process needs to be specified in device name after type, for example:
s dev="|PIPE|dir /w"this device runs dir command with parameter /w.
MiniM create child process in the open command applied to |PIPE| device. Open command executes successfully if child process created. Other child process execution depends on process specification.
Run child process
To illustrate child process creation use command mkdir to create child subrirectory.
s dev="|PIPE|mkdir subdir" o dev c devHere we specify device name to run mkdir process with parameter subdir. Child process creates on open command. On close command MiniM process forgets child process. In this example creates child subdirectory subdir.
Run child process with output redirection
To specify child process's output redirection we need to use redirection symbol >. This symbol use command processor cmd.exe. Redirection symbol and file to output to need to be specified in the device name. For example, dir command with output redirection can be run as:
s dev="|PIPE|dir /w > dir.txt" o dev c devHere we create |PIPE| device to run internal operating system command dir with parameter /w and with output redirection to file dir.txt. On execution this example we got file dir.txt with dir command's output.
Run child process with intercept stdout channel
To get child process's stdout output we need to create |PIPE| device, open to read, make current and read from current device.
dir ; n zeof=$v("proc",5,0) n dev="|PIPE|dir /w" o dev:("rwt") n result u dev f q:$zeof r result($i(result)) u $p c dev i $v("proc",5,zeof) zw result qHere we run child process dir with parameter /w througth |PIPE| device, make this device current and read all content in text mode line-by-line.
Here we use function $v("proc",5) to control $zeof system variable behavior.
Here we read child's output content into local variable result using read command:
r result($i(result))After read end we write all content to current input-output device as local variable content.
Run child process with write to his stdin channel and read from his stdout channel
To run external child process with writing to his stdin channel and reading from his stdout channel we need to create |PIPE| device with read and write options. After opening we make device current, write to device and read from device.
Windows operating systems has stdin-stdout specific. After first child process's stdout reading we cannot write to his stdin channel, in Windows it is impossible. MiniM process after first read command automatically make |PIPE| device read-only and close child process's stdin channel.
Here is example how to run child process as sort operating system command. This program read from his stdin channel all content, sorts this line-by-line and outputs to his stdout output channel. To operate stdin and stdout channels we can use external file or other process redirections.
runext ; n zeof=$v("proc",5,0) n dev="|PIPE|sort",line o dev:("rwt") u dev n i=0 f s i=$o(^ROUTINE($zname,i)) q:i="" d . w $g(^ROUTINE($zname,i)),! f q:$zeof d . r line u $p w line,! u dev u $p c dev i $v("proc",5,zeof) qHere MUMPS program reads own's text from ^ROUTINE global line-by-line and writes his into |PIPE| device for sort command. After this reads from device line-by-line and writes lines to current principal device. After first read command execution MiniM closes child's stdin channel and this is signal to child process to sort all content. First read command reads already sorted content.
Example screen of this program execution:
USER>d ^runext . r line u $p w line,! u dev . w $g(^ROUTINE($zname,i)),! c dev f q:$zeof d i $v("proc",5,zeof) n dev="|PIPE|sort",line n i=0 f s i=$o(^ROUTINE($zname,i)) q:i="" d n zeof=$v("proc",5,0) o dev:("rwt") q u $p u dev runext ;Eugene Karataev