Runs an executable or shell command in a subshell.
system
open-pipe command &key direction element-type interrupt-off shell-type use-pty save-exit-status external-format => stream
command⇩ |
A string, a list of strings, a simple-vector of strings, or nil . |
direction⇩ | |
element-type⇩ |
A type specifier. |
interrupt-off⇩ |
A boolean. Not implemented on Microsoft Windows. |
shell-type⇩ |
A shell type. |
use-pty⇩ |
A boolean. |
save-exit-status⇩ | |
external-format⇩ |
stream⇩ |
A pipe stream. |
The function open-pipe
runs an executable or shell command with its input and/or output connected to a stream.
On non-Windows platforms the behavior of open-pipe
is analogous to that of popen
in the POSIX C library. It creates a pipe to/from a subprocess and returns a stream. The stream can be read from or written to as appropriate.
On Microsoft Windows open-pipe
calls CreateProcess
and CreatePipe
and returns a bidirectional stream.
command is interpreted as by call-system-showing-output.
direction is a keyword for the stream direction. The default value is :input
. Bidirectional (I/O) pipes may be created by passing :io
. See the example below. direction can also be :none
, which means no input and no output like call-system, but is useful when you want to use pipe-exit-status and pipe-kill-process. On Windows it is not possible to open a unidirectional pipe, so :input
and :output
both have the same effect as :io
.
When save-exit-status is non-nil, the status of the child process that open-pipe
creates is tracked, so pipe-exit-status and pipe-kill-process can be used reliably. The default value of save-exit-status is nil
.
external-format specifies the external format to use if it is not :default
. See 26.6 External Formats to translate Lisp characters from/to external encodings for a description of external formats.
On non-Windows platforms, if external-format is :default
and element-type is also :default
(the defaults), then LispWorks tries to determine the external format to use using the POSIX environment variables LC_ALL
, LC_CTYPE
and LANG
(in that order). If external-format is :default
and element-type is not :default
or it fails to find a known external format, open-pipe
creates a stream that does not use an external format.
On Windows if external-format is :default
it does not use external format.
Note that external-format is new in LispWorks 8.0. In previous versions, open-pipe
never used an external format.
element-type specifies the type of the stream as with open. It defaults to :default
, which causes open-pipe
to choose the appropriate element-type for external-format, as determined by ef:external-format-type. If there is no external format, it chooses base-char.
interrupt-off, if t
, ensures that Ctrl+C
(SIGINT) to the LispWorks image is ignored by the subprocess. This argument is not implemented on Microsoft Windows.
shell-type specifies the type of shell to run. On Unix-like systems the default value is "/bin/sh"
. On Microsoft Windows the default value is "cmd"
.
use-pty is useful on Unix-like systems if the sub-process behaves differently when running interactively and non-interactively. When use-pty is non-nil, the input and output of the sub-process are opened using PTY (Pseudo-pty). That means that the sub-process sees its input and output as if they come from an interactive terminal. The PTY also processes special characters such as Ctrl-C the same way that an ordinary TTY does.
use-pty is probably not useful on Microsoft Windows as there is no concept corresponding to the Unix behavior. If use-pty is non-nil then it uses the CREATE_NEW_PROCESS_GROUP
flag when creating the child, but it is not obvious when this might be useful.
stream supports mixed character and binary I/O in the same way as file streams constructed by open.
When open-pipe
is called on non-Windows platforms and neither of external-format or element-type are supplied, then it may choose an external format based on environment variables hence and behave differently from previous versions, and also between different environments. If the data that is passed in the pipe conforms to the external format specified by the environment variables, for example it is the output of standard Unix utilities, that is the useful behavior. Otherwise, you should supply the required external-format or element-type to control it. If you use sys:open-pipe in previous versions of LispWorks without supplying element-type and you want it to continue to not process the data using an external-format, then supply element-type with base-char if you want code to work on all versions of LispWorks.
Example on Unix:
CL-USER 1 > (setf *ls* (sys:open-pipe "ls")) Warning: Setting unbound variable *LS* #<SYSTEM::PIPE-STREAM "ls"> CL-USER 2 > (loop while (print (read-line *ls* nil nil))) "hello" "othello" NIL NIL CL-USER 3 > (close *ls*) T
The following example shows you how to use bidirectional pipes.
CL-USER 1 > (with-open-stream (s (sys:open-pipe "/bin/csh" :direction :io)) (write-line "whereis ls" s) (force-output s) (read-line s)) "ls: /sbin/ls /usr/bin/ls /usr/share/man/man1.Z/ls.1" NIL
Example on Microsoft Windows:
CL-USER 40 > (setf *ls* (sys:open-pipe "dir")) #<WIN32::TWO-WAY-PIPE-STREAM 205F03F4> CL-USER 41 > (loop while (print (read-line *ls* nil nil))) " Volume in drive Z is lispsrc" " Volume Serial Number is 82E3-1342" "" " Directory of Z:\\v42\\delivery-tests" "" "20/02/02 11:57a <DIR> ." "20/02/02 11:57a <DIR> .." "14/02/02 07:04p 6,815,772 othello.exe" "14/02/02 07:07p 6,553,628 hello.exe" " 4 File(s) 13,369,400 bytes" " 3,974,103,040 bytes free" NIL NIL CL-USER 42 > (close *ls*) T
This last example illustrates the use of save-exit-status. This form runs LispWorks as a subprocess such that it quits immediately with exit status 1623:
(setq *sub* (sys:open-pipe (list (lisp-image-name) "-eval" "(quit :status 1623)") :save-exit-status t))
This form then returns 1623:
(sys:pipe-exit-status *sub*)
call-system
call-system-showing-output
pipe-exit-status
pipe-kill-process
pipe-close-connection
LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:31:02