如何通过临时文件将数据传输到其他进程

How to pipe data to other process via temporary file

我想将一些数据从我的程序发送到通过 uiop:run-program 执行的进程。

以下作品:

(require :asdf)
(asdf:load-system :uiop)
(uiop:with-temporary-file (:stream dot-program-stream
                           :pathname dot-program-file)
  (format dot-program-stream "digraph g { n1 -> n2; }")
  (finish-output dot-program-stream)
  :close-stream
  (uiop:with-temporary-file (:pathname png-data)
    (uiop:run-program '("/usr/bin/dot" "-Tpng") :input dot-program-file
                                                :output png-data)
    (uiop:launch-program '("/usr/bin/display") :input png-data)))

好像比较绕口。

一个更简单的版本,我只使用了一个流,没有 finish-output 也没有使用 :close-stream 标签导致 dot 产生了一个空的 0 字节文件。

如何执行进程并将我的 lisp 程序生成的数据作为标准输入传递给它?

仔细查看 uiop:launch-programuiop:run-program 的文档,尤其是 :input:output 键的选项。

您可以用 :input :stream 调用 launch-programLaunch-program returns 一个进程信息对象,它包含连接到访问器后面该程序的标准输入的流 process-info-input,因此您可以打印到它。

如果您有不同的程序生成应进入该输入流的输出,您有多种选择:

  • 创建一个临时文件,然后读取它并将其打印到第二个程序的输入流(这似乎是您当前的做法)
  • 第一次调用使用 run-program:output :string,然后第二次使用 launch-program:input :stream,并将第一次的输出写入该流
  • 第一次调用也使用 launch-program,在本例中使用 :output :stream,然后从该输出读取并将其打印到第二个程序的输入

您可以先读取所有内容,然后再写入所有内容,或者您​​可以进行缓冲读取和写入,这对于长 运行 进程可能很有趣。

您还可以使用 OS 中的 fifo(命名管道)代替进程内缓冲。