Piping between Common Lisp and external command line
With the external-program package, I can code to call an external command line program easily. For example:
(external-program:run "ls" '("-l") :output *standard-output*)
What if I want to keep streaming (piping) input and reading output. (1) instead of run, I use start.
(setf *x* (external-program:start "cat" '() :output :stream :input :stream))
(2) I create a thread for reading the output and print it. Bordeaux-threads API looks quite similar to POSIX.
(setf *read-thread*
(bordeaux-threads:make-thread
(lambda ()
(loop for line = (read-line (external-program:process-output-stream *x*) nil)
while line
do (format t "OUT: ~A~%" line)))
:name "titi"))
(3) I get an output stream for passing data to the external program.
(setf *out* (external-program:process-input-stream *x*))
(4) I write something to out and flash it.
(progn
(loop for i from 1 to 10
do (format *out* "!!! ~A~%" i))
(force-output *out*))
At this step, you should see some output from the (2) step, which are:
OUT: !!! 1
OUT: !!! 2
...
OUT: !!! 10
You can keep playing with it.
(5) And finally I clean everything up.
(close *out*)
(bordeaux-threads:join-thread *read-thread*)