ext:run-program — Start and communicate with a child process.


(ext:run-program command argv &key input output error)


One of :STREAM, T or NIL, defaults to :STREAM


One of :STREAM, T or NIL, defaults to :STREAM


One of :OUTPUT, T or NIL, defaults to :STREAM


This function creates a external process by launching the program command with the arguments from the list argv.

The arguments input, output and error are used to intercept the standard input, output and error streams of the program. A value of :STREAM means a lisp stream will be created to communicate with the child process. A value of NIL means that the data from this pipe will be discarded. The vaule of T means that the child process will use the parent's standard input, output or error channels. For instance, if ECL writes to the console and you pass a value of output equal to :STREAM, the child process will also output to the console. Finally, the error messages of the child process are redirected to the same pipe as its standard output when error takes the value :OUTPUT.

If the child process was succesfully launched, this function outputs a lisp stream to which we one may write, read or do both things, depending on the arguments input and output. If an error happened during the preparation of the child process (for instance the program was not found), this function returns NIL.

The design of this function is inspired by the function of same name in CMUCL and SBCL.


List all users in a Unix system. We use the sed command to parse the file with the list of users, removing comments and information other than the user names:

(defun all-users (&optional (file "/etc/passwd"))
  (let ((s (ext:run-program "sed"
              (list "-e" "/^#.*$/d;/^[^:]*$/d;s,^\\([^:]*\\).*$,\\1,g"
              :input NIL :output :STREAM :error NIL)))
    (unless s
      (error "Unable to parse password file"))
    (loop for x = (read s NIL NIL)
          while x
          collect x)))

Make a directory. Redirect standard error output to the same as the output:

(ext:run-program "mkdir" '("./tmp") :output :STREAM :error :OUTPUT)

Same as before, but now both the output and the standard error are discarded

(ext:run-program "mkdir" '("./tmp") :output NIL :error :OUTPUT)