2012-05-10 19 views
8

他の言語(たとえば、bashおよびPythonなど)では、子プロセスを生成するときに、この新しいプロセスが親からstdoutおよびstderrを継承します。これは、子プロセスからのすべての出力が、親からの出力だけでなく端末にも出力されることを意味します。子プロセスstdout/stderrをJavaのメインプロセスstdout/stderrにリダイレクトする方法は?

Javaでどのように同じ動作を達成できますか?

私の最初の試みでした:

proc = Runtime.getRuntime().exec(cmd); 

しかし、それは動作しません。 this answerthis answerに基づいて、私は、コードを交換しました:

ProcessBuilder pb = new ProcessBuilder(cmd); 
pb.redirectOutput(System.out); 
pb.redirectError(System.err); 

しかし、引数が期待されるメソッドのパラメータと互換性がないとして、これはさらに、コンパイルされません。

答えて

13

作成したプロセスの出力ストリームとエラーストリームを読み込み、出力先の場所(System.outとSystem.errの場合)に出力する必要があります。

編集。上記の答えは、それは代わりに、それは確かに可能だ

processBuilder.redirectOutput(Redirect.INHERIT) 
+1

...

public static class InputStreamConsumer extends Thread { private InputStream is; public InputStreamConsumer(InputStream is) { this.is = is; } @Override public void run() { try { int value = -1; while ((value = is.read()) != -1) { System.out.print((char)value); } } catch (IOException exp) { exp.printStackTrace(); } } } private void captureOutput(Process p) { InputStreamConsumer stdout; InputStreamConsumer errout; errout = new InputStreamConsumer(p.getErrorStream()); stdout = new InputStreamConsumer(p.getInputStream()); errout.start(); stdout.start(); } 

....何かのように内部で実行されている:私は当初、私は私がInputStreamConsumerをコーディングしなければならなかっただろう実現、「簡単」と述べました1つのストリームから読み込みを続け、別のストリームに書き込むループを実装しますか?申し訳ありませんが、実行可能ではありません。あまりにも多くの作業(おそらく新しいスレッドで実行する必要があり、バグの可能性のある点がたくさんあります)。 –

+2

実行可能かどうかはこれまで必要とされていたものです。私はちょうどJava 7 APIをチェックして、それは対処されているように見えます - あなたはRedirect.INHERITであなたが望むものを達成するために見えるredirectOutputを呼び出すことができるようになりました。 – henry

1

を呼び出すことが可能になりそうだのjavadocから7のようなJava < 7の正しいです。 Ant Javaタスクは、forkがtrueに設定されている場合にこれを行います。私はすべての詳細を覚えていませんが、素早く見ると、ほとんどの魔法はPumpStreamHandlerにあるようです。あなたはそれからインスピレーションを見つけることを試みるかもしれません。

+1

実際にはそれよりも簡単ですが、ProcessBuilder.redirectOutput()を使用しているので使用しているように見える1.7ではpb.redirectOutput(Redirect.INHERIT)を実行するだけです。私は自分でそれをしたことはありませんが。 – asudell

3

これはそれほど悪くありません。あなたは私がする必要があることを意味

ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/D", "/C", myCommand, parm, parm...); 
    try { 
     System.out.println("Start "+myCommand); 
     Process myProcess = pb.start(); 
     captureOutput(myProcess); 

     int returnCode = myProcess.waitFor(); 
     System.out.println("myProcess: return code : "+returnCode); 
    } 
    catch (IOException e) { 
     e.printStackTrace(); 
    } 
+0

IDE以外のものは私にとってはうまくいきませんでした。これは、ありがとうございました。 – Steve

+1

見栄えは良いですが、このような自己実装コードを使用する必要がありますか? Javaでは、STDERRをSTDOUTにリダイレクトしてから、それらの組み合わせを1つの入力ストリームから読み込むことはできません。 – SomethingSomething

関連する問題