I'm trying to figure out how to use the output stream of one program I start with RUN-PROGRAM
so it can be used as the input of another program started with RUN-PROGRAM
(i.e., the moral and perhaps literal equivalent of piping). I've tried using a number of combinations of the :INPUT
, :OUTPUT
and :WAIT
keyword arguments, but nothing I've hit
upon has been productive so far. Any tips would be helpful; for example, how would I go about doing something like ls | grep lisp
from the shell?
One of my attempts is
(defun piping-test ()
(let ((grep-process (run-program "/usr/bin/grep" '("lisp")
:input :stream
:output :stream)))
(unwind-protect
(with-open-stream (s (process-input grep-process))
(let ((ls-process (run-program "/bin/ls" '()
:output s)))
(when ls-process
(unwind-protect
(with-open-stream (o (process-output grep-process))
(loop
:for line := (read-line o nil nil)
:while line
:collect line))
(process-close ls-process)))))
(when grep-process (process-close grep-process)))))
Running this in a SLIME REPL causes everything to hang until I break
with C-c C-c
, so it's pretty obviously not the right thing, but I'm
not sure how to change it so it is the right thing.
EDIT: Adding :WAIT NIL
to both RUN-PROGRAM
invocations, or to only the invocation for grep
, doesn't do the trick. In that case, the function will hang, and breaking with C-c C-c
gets a stack trace indicating that there's a local function (defined via FLET
) called SB-UNIX:SELECT
that has hung.