问题描述
我试图弄清楚如何使用以RUN-PROGRAM
开头的一个程序的输出流,以便可以将其用作以RUN-PROGRAM
开头的另一个程序的输入(即,道德上的,也许是文字上的等价物)管道).我尝试使用:INPUT
,:OUTPUT
和:WAIT
关键字参数的多种组合,但没有任何反应迄今已取得成果.任何提示都会有所帮助;例如,我将如何在shell中执行类似ls | grep lisp
的操作?
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 hitupon 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?
我的尝试之一是
(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)))))
在SLIME REPL中运行此命令会导致一切挂起,直到我摔坏为止使用C-c C-c
,显然这不是正确的选择,但是我不知道如何更改它,所以这是正确的事情.
Running this in a SLIME REPL causes everything to hang until I breakwith C-c C-c
, so it's pretty obviously not the right thing, but I'mnot sure how to change it so it is the right thing.
编辑:将:WAIT NIL
添加到两个RUN-PROGRAM
调用中,或仅添加到grep
的调用中,并不能解决问题.在这种情况下,该函数将挂起,并用C-c C-c
中断会得到一个堆栈跟踪,表明有一个名为SB-UNIX:SELECT
的本地函数(通过FLET
定义)已挂起.
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.
推荐答案
我在 comp.lang.lisp .他的解决方案是针对CMUCL的,但是它在紧密相关的SBCL上使用了实质上相同的RUN-PROGRAM
函数,并且进行了较小的更改也可以在CCL上使用,因为CCL的RUN-PROGRAM
本质上是CMUCL/的克隆. SBCL.
I got a working answer from Raymond Toy on comp.lang.lisp. His solution was for CMUCL, but it worked with the essentially identical RUN-PROGRAM
function on the closely related SBCL, and with minor changes it will work on CCL as well, because CCL's RUN-PROGRAM
is basically a clone of the one from CMUCL/SBCL.
秘密在于,首先设置ls
进程,然后将其输出流作为输入提供给grep
进程,就像这样:
The secret, as it were, is to set up the ls
process first, and then provide its output stream to the grep
process as input, like so:
(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-PROGRAM
调用中的RUN-PROGRAM
省略:WAIT NIL
参数,并且效果也很好.
I also experimented with omitting the :WAIT NIL
argument from the RUN-PROGRAM
call for ls
, and it worked just as well.
这篇关于如何在Steel Bank Common Lisp中处理输入和输出流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!