8

clojureでサブプロセスを起動して(javaで問題ありません)、その出力をリアルタイムでstdoutに直接送信する方法を探しています。私が見つけた最も近いものはclojure用のConchライブラリで、これを使用すると出力をに送信できますが*out*、プロセスの実行が完了するまで実際には出力は表示されません。

4

2 に答える 2

5

このための便利なClojureラッパーがあるかどうかわからない:

(->> (.. Runtime getRuntime (exec "ls") getInputStream)                                                                                                                   
    java.io.InputStreamReader.                                                                                                                                            
    java.io.BufferedReader.                                                                                                                                               
    line-seq                                                                                                                                                              
    (map println))  

実際には、stdinとstderrの両方を定期的に読み取る必要があります。そうしないと、バッファの1つがいっぱいになるとプロセスがハングする可能性があります。

于 2013-01-19T00:35:20.563 に答える
5

アーサーの答えは私を解決策に導いたので正しいとマークしました、そしてそれは基本的に誰かが基本的なケースで望むものです。私は結局、もっと多くのことをするより大きな方法を構築することになり、他の誰かがそれが役に立つと思った場合に備えて、ここにそれを置くと思いました

(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 に答える