Pil*_*lsy 10 lisp sbcl common-lisp
我正在试图弄清楚如何使用我开始的一个程序的输出流,RUN-PROGRAM因此它可以用作另一个程序的输入RUN-PROGRAM(即道德,也许是文字等效的管道).我已经使用了一些组合的尝试:INPUT,:OUTPUT和:WAIT关键字参数,但没有我打后一直生产至今.任何提示都会有所帮助; 例如,我将如何ls | grep lisp从shell中做一些事情?
我的一个尝试是
(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)))))
Run Code Online (Sandbox Code Playgroud)
在SLIME REPL中运行它会导致一切都挂起,直到我打破C-c C-c,所以它显然不是正确的事情,但我不知道如何改变它所以它是正确的.
编辑:添加:WAIT NIL到两个RUN-PROGRAM调用,或仅添加到调用grep,不起作用.在这种情况下,函数将挂起,并且中断C-c C-c获取堆栈跟踪,指示存在已挂起的本地函数(定义为via FLET)SB-UNIX:SELECT.
Pil*_*lsy 10
我在comp.lang.lisp上得到了Raymond Toy的工作答案.他的解决方案是针对CMUCL的,但它在RUN-PROGRAM密切相关的SBCL上使用了基本相同的功能,并且稍微改变它也适用于CCL,因为CCL RUN-PROGRAM基本上是来自CMUCL/SBCL的克隆.
事实上,秘密是首先设置ls进程,然后将其输出流grep作为输入提供给进程,如下所示:
(defun piping-test2 ()
(let ((ls-process (run-program "/bin/ls" '()
:wait nil
:output :stream)))
(unwind-protect
(with-open-stream (s (process-output ls-process))
(let ((grep-process (run-program "/usr/bin/grep" '("lisp")
:input s
:output :stream)))
(when grep-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 grep-process)))))
(when ls-process (process-close ls-process)))))
Run Code Online (Sandbox Code Playgroud)
我也尝试省略了调用中的:WAIT NIL参数,并且它的工作原理也一样.RUN-PROGRAMls