【问题标题】:SBCL: Gather output of run-program process while runningSBCL:在运行时收集运行程序进程的输出
【发布时间】:2015-05-23 15:11:16
【问题描述】:

尊敬的 StackExchange 会员,

我最近开始玩弄 Common Lisp,并想创建一个 Web 界面来管理经过改装的 Minecraft 服务器。我已经尝试过this solution,但在这种情况下,函数只是挂起并且永远不会返回。

我的代码如下所示:

(defvar *proc*)

(defun create-minecraft-proc ()
  (let* ((binary "/usr/bin/java")
    (jar "/home/user/temp/Vanilla 1.8/minecraft.jar")
    (dir "/home/user/temp/Vanilla 1.8")
    (args (list "-jar" jar "nogui")))
    (setf *proc* (sb-ext:run-program binary args :directory dir :wait nil :input :stream :output :stream))))

(defun copy-stream (in out)
  (loop for line = (read-line in nil nil)
     while line
       do (write-line line out)))

(defun get-minecraft-output ()
  (with-open-stream (proc-stream (process-output *proc*))
    (with-output-to-string (out)
      (copy-stream (process-output *proc*) out)))

我怎样才能得到一个包含完整进程输出的字符串,而不必等待它终止?

【问题讨论】:

    标签: subprocess common-lisp sbcl


    【解决方案1】:

    通过/bin/cat 进行实验,我发现了一些可能对您有所帮助的东西。

    首先,在写入进程的输入后始终使用finish-output

    (format (process-input *cat*) "Hello~%")
    (finish-output (process-input *cat*))
    

    否则,在您关闭输入流之前,输入可能无法到达子进程。如果 Minecraft 在生成任何输出之前需要输入,那么 尝试在没有所需输入的情况下从其输出中读取将导致 SBCL 挂起,这种方式无法在 SLIME 中使用 C-c C-c 恢复。

    其次,使用listen判断是否产生了任何输出:

    (when (listen (process-output *cat*))
        (read-line (process-output *cat*)))
    

    使用 finish-outputlisten,我能够避免在从 cat 的标准输出增量读取时挂起。

    【讨论】:

    • 效果很好,非常感谢。尤其是关于完成输出的部分,因为接下来我要做的就是向 Minecraft 服务器发送命令。
    猜你喜欢
    • 2013-01-25
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 2012-04-06
    • 2011-05-23
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多