我希望尝试使用cl-async来运行一系列具有大量命令行参数的外部程序。但是,我无法弄清楚如何阅读使用as:spawn
启动的流程的标准输出。
我通常会使用uiop,这样可以轻松捕获过程输出:
(let ((p (uiop:launch-program ... :output :stream)))
(do-something-else-until-p-is-done)
(format t "~a~%" (read-line (uiop:process-info-output p))))
我已经尝试了:output :pipe
和:output :stream
两个as:spawn
选项,并且在我的退出回调中执行(as:process-output process-object)
会显示相应的管道或异步流对象但是我无法弄清楚如何阅读它们。
任何有此库经验的人都可以告诉我们如何实现这一目标吗?
答案 0 :(得分:1)
所以你去你的repl并输入:
CL-USER> (documentation 'as:spawn 'function)
你阅读出来的任何内容(或者把你的观点放在符号上并点击C-c C-d f
)。如果您阅读它,您会看到:input
等参数的格式为:pipe
,(:pipe args...)
,:stream
或(:stream args...)
(或某些其他选择)。并且:stream
的行为类似于:pipe
,但提供了不同类型的输出,并且对于args的详细信息,应该查看PIPE-CONNECT
,因此您可以查看文档。那么它告诉你选项是什么,但它不是很有用。什么是PIPE
或STREAM
的文档/说明?事实证明,管道是STREAMISH
的类和子类。那个PROCESS
也是一个类,它有PROCESS-OUTPUT
之类的插槽(和访问器)。那么如何确定下一步该做什么的好计划呢?这是一个建议:
cat foo.txt -
说:output :stream :input :pipe
)
C-c C-v TAB
)PROCESS
的一个实例。什么是输出?检查ASYNC-STREAM
)。把它放到你的repl中,看看如果你试着读它会发生什么?以上都是猜测。我没有试过运行任何这个,但你应该。或者,查看库的源代码。它已经在你的计算机上了,如果你找不到它就在GitHub上。只有大约六个源文件,它们都很小。只需阅读它们,看看你能学到什么。或者转到您想要了解的符号,然后点击M-.
直接跳到其定义。然后阅读代码。然后看看你是否能弄明白该做什么。
答案 1 :(得分:1)
我在测试套件中找到了答案。输出流只能通过读回调异步处理。以下是后人的简单示例
(as:start-event-loop
(lambda ()
(let ((bytes (make-array 0 :element-type '(unsigned-byte 8))))
(as:spawn "./test.sh" '()
:exit-cb (lambda (proc exit-status term-signal)
(declare (ignore proc exit-status term-signal))
(format t "proc output:~%~a"
(babel:octets-to-string bytes)))
:output (list :stream
:read-cb (lambda (pipe stream)
(declare (ignore pipe))
(let ((buf (make-array 128 :element-type '(unsigned-byte 8))))
(loop for n = (read-sequence buf stream)
while (plusp n) do
(setf bytes
(concatenate '(vector (unsigned-byte 8))
bytes
(subseq buf 0 n)))))))))))
与
$ cat test.sh
#!/bin/bash
sleep_time=$((1+$RANDOM%10))
echo "Process $$ will sleep for $sleep_time"
sleep $sleep_time
echo "Process $$ exiting"
产生预期的输出