The following procedures are similar to the
pclose system routines. The code is in a separate “popen”
(use-modules (ice-9 popen))
Execute a command in a subprocess, with a pipe to it or from it, or with pipes in both directions.
open-piperuns the shell command using ‘/bin/sh -c’.
open-pipe*executes prog directly, with the optional args arguments (all strings).
mode should be one of the following values.
OPEN_READis an input pipe, ie. to read from the subprocess.
OPEN_WRITEis an output pipe, ie. to write to it.
For an input pipe, the child's standard output is the pipe and standard input is inherited from
current-input-port. For an output pipe, the child's standard input is the pipe and standard output is inherited from
current-output-port. In all cases cases the child's standard error is inherited from
current-error-port(see Default Ports).
current-X-portsare not files of some kind, and hence don't have file descriptors for the child, then /dev/null is used instead.
Care should be taken with
OPEN_BOTH, a deadlock will occur if both parent and child are writing, and waiting until the write completes before doing any reading. Each direction has
PIPE_BUFbytes of buffering (see Ports and File Descriptors), which will be enough for small writes, but not for say putting a big file through a filter.
OPEN_READ.(let* ((port (open-input-pipe "date --utc")) (str (read-line port))) (close-pipe port) str) ⇒ "Mon Mar 11 20:10:44 UTC 2002"
OPEN_WRITE.(let ((port (open-output-pipe "lpr"))) (display "Something for the line printer.\n" port) (if (not (eqv? 0 (status:exit-val (close-pipe port)))) (error "Cannot print")))
Close a pipe created by
open-pipe, wait for the process to terminate, and return the wait status code. The status is as per
waitpidand can be decoded with
status:exit-valetc (see Processes)
waitpid WAIT_ANYshould not be used when pipes are open, since it can reap a pipe's child process, causing an error from a subsequent
close-port (see Closing) can close a pipe, but it doesn't
reap the child process.
The garbage collector will close a pipe no longer in use, and reap the
child process with
waitpid. If the child hasn't yet terminated
the garbage collector doesn't block, but instead checks again in the
Many systems have per-user and system-wide limits on the number of processes, and a system-wide limit on the number of pipes, so pipes should be closed explicitly when no longer needed, rather than letting the garbage collector pick them up at some later time.