You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何捕获cl-async:spawn启动进程的标准输出?

解决cl-async中读取spawn进程标准输出的问题

我之前也踩过这个坑!cl-async是异步IO框架,和uiop那种同步阻塞的处理思路完全不一样——你不能用同步read-line那套逻辑来拿输出,得靠回调来处理异步推送的数据流。

你试过:output :pipe其实是对的,但关键是要绑定read-cb回调来接收输出,而不是试图同步读取。下面给你两个实用的示例:

实时打印进程输出

这个示例会在进程输出内容时实时打印:

(as:with-event-loop ()
  (as:spawn "your-program" '("--arg1" "value1" "--arg2" "value2")
            :output :pipe
            ;; 每次读取到新输出时触发这个回调
            :read-cb (lambda (data)
                       ;; 注意:部分场景下data是字节数组,需要转成字符串
                       (let ((output-str (if (stringp data)
                                            data
                                            (babel:octets-to-string data))))
                         (format t "Process output: ~a~%" output-str)))
            ;; 进程退出时触发的回调
            :exit-cb (lambda (exit-code signal)
                       (format t "Process finished with exit code ~a (signal: ~a)~%" exit-code signal)
                       (as:exit-event-loop))))

收集完整输出后再处理

如果需要等进程结束后拿到全部输出,可以用一个可调整数组来缓存:

(as:with-event-loop ()
  ;; 初始化一个可动态扩展的字符串缓存
  (let ((full-output (make-array 0 :element-type 'character
                                   :adjustable t :fill-pointer t)))
    (as:spawn "ls" '("-la")
              :output :pipe
              :read-cb (lambda (data)
                         (let ((str (if (stringp data)
                                        data
                                        (babel:octets-to-string data))))
                           ;; 将新输出追加到缓存里
                           (format full-output "~a" str)))
              :exit-cb (lambda (exit-code signal)
                         (format t "=== Full Process Output ===~%~a~%" full-output)
                         (format t "Exit code: ~a~%" exit-code)
                         (as:exit-event-loop)))))

关键注意点:

  • 别试图在as:spawn之后直接同步读取输出——cl-async的事件循环还没启动,异步IO操作根本没开始,你拿不到任何数据。
  • 关于data的类型:如果你的cl-async配置了使用字节流,回调会收到字节数组,这时候需要用babel:octets-to-string(确保你已经加载了babel库)转成字符串;如果是字符串模式,直接用就行。
  • cl-async的核心是非阻塞异步回调,所有和进程IO相关的逻辑都要放到对应的回调里处理,这和uiop的同步阻塞模型是本质区别。

内容的提问来源于stack exchange,提问作者ptb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:27:30