我正在寻找一种在 clojure 中启动子进程的方法(java 可以)并将其输出实时直接发送到标准输出。我能找到的最接近的是 clojure 的 Conch 库,它允许您将输出发送到*out*
,但在进程完成运行之前它实际上不会显示输出。
问问题
879 次
2 回答
5
不确定是否有一个方便的 Clojure 包装器:
(->> (.. Runtime getRuntime (exec "ls") getInputStream)
java.io.InputStreamReader.
java.io.BufferedReader.
line-seq
(map println))
在实践中值得注意的是,您需要定期读取 stdin 和 stderr ,否则当其中一个缓冲区填满时,进程可能会挂起。
于 2013-01-19T00:35:20.563 回答
5
我将 Arthur 的答案标记为正确,因为它引导我找到了解决方案,这基本上是人们在基本情况下想要的。我最终构建了一个更大的方法,它虽然做得更多,但我想我会把它放在这里以防其他人发现它有用
(defn- print-return-stream
[stream]
(let [stream-seq (->> stream
(java.io.InputStreamReader.)
(java.io.BufferedReader.)
line-seq)]
(doall (reduce
(fn [acc line]
(println line)
(if (empty? acc) line (str acc "\n" line)))
""
stream-seq))))
(defn exec-stream
"Executes a command in the given dir, streaming stdout and stderr to stdout,
and once the exec is finished returns a vector of the return code, a string of
all the stdout output, and a string of all the stderr output"
[dir command & args]
(let [runtime (Runtime/getRuntime)
proc (.exec runtime (into-array (cons command args)) nil (File. dir))
stdout (.getInputStream proc)
stderr (.getErrorStream proc)
outfut (future (print-return-stream stdout))
errfut (future (print-return-stream stderr))
proc-ret (.waitFor proc)]
[proc-ret @outfut @errfut]
))
于 2013-05-18T19:05:23.563 回答