2017-03-14 8 views
0

STDOUTとSTDERRを無視してJavaからシステムコマンドを実行する方法はありますか?例えば、私は次のことを試してください。Java Run Systemコマンドと出力を無視する

Process p = Runtime.getRuntime().exec("some_executable_path param1 param2 >NUL 2>&1"); 

Javaはコマンドを解析しようとすると、(例えば、リダイレクトされる出力を防止する)引数を脱出してしまいます。 STDOUT/STDERRをリダイレクトしないと、バッファがいっぱいになり、システムコールが終了しなくなります。以下は、私が欲しいものを行いますが、非常に面倒であるだけ離れたシステムコールの出力を投げるために高価なリソースを作成します。

ProcessBuilder pb = new ProcessBuilder("some_executable_path", "param1", "param2"); 
pb.redirectErrorStream(true); 
final Process p = pb.start(); 
final Thread redirectToNull = new Thread(() -> { 
     final InputStream stdout = process.getInputStream(); 
     try { 
      while (stdout.read() != -1); 
     } catch (final Exception e) { 
      // Don't care 
     } 
    }, "Output Consumer Thread"); 
redirectToNull.setDaemon(true); 
redirectToNull.start(); 

私は、Javaの設計チームが自虐ことが知られているが、これはばかげているされて実現します。上記のコードを使用するのではなく、アプリケーションでシステムコールをラップするバッチまたはPerlスクリプトを提供することをお勧めします。これを達成するためのより簡単な方法が必要です。

それで、問題は、Java内からシステムコマンドを実行し、STDOUT/STDERRに出力された出力を無視しても問題ありませんか?

+1

あなたはすべきですストリームからの出力を取得しますが、何もしないでください。それ以外の場合は、プロセスバッファが不足する可能性があります(私はそれがその用語だと思います)。 –

+1

「誰にでも喜ばせる方法」の問題の1つです。あなたは必要な特定のタスクを実行するためのコードを簡素化するライブラリコードの小さな部分を書くことができます。必要に応じてこれを再利用することができます – MadProgrammer

+0

移植性を犠牲にして、(1)invokeあなたのコマンドを実行するシェル。コマンドラインでのリダイレクトが機能します。または(2)リダイレクト先の '/ dev/null'(またはターゲットシステムにあるもの)を指定します。私があなたの例からWindozeにいると推測しているように答えとして投稿していない、これらのハックはどちらもうまくいきません。 –

答えて

2

Javaがリダイレクトを防止するのではなく、肯定的にそれを行うのではなく、どちらもあなたのプログラムではありません。 CMDにprogram arg1 arg2 >out 2>err <inのようなコマンドを与えると、そのリダイレクトを設定してprogramarg1 arg2だけで呼び出すのは>outではないCMDです。Unixではシェルはいくつか選択できますが、すべてそのようなリダイレクトを処理します。同様に、パイプはCMDまたはシェルによって設定され、いずれかまたはすべてのプログラムがのパイプで実行するのではありません。

このようにWindows上でこれを行う方法は、CMDを実行し、それがリダイレクトを行う必要がありどちらかである:(Java7 +を想定)

Process p = new ProcessBuilder ("cmd", "/c", "program arg1 arg2 >NUL 2>&1").start(); 
// this uses CMD's default parsing for args, so they must not contain space 
// unless you insert 'data' quotes, or things that look like a substitutable %var% 

かをリダイレクトを行うためにProcessBuilderを伝える:

pb.redirectOutput (new File("NUL")).redirectErrorStream(true) 
+0

2つめのオプションは、OSに依存している必要があるのはnullデバイスの名前だけなので、私が行ったことです。これは、Windowsでは* "NUL" * Linuxでは* "/ dev/null" *です。私はそのようなファイルが 'File'クラスのpublic static定数ではないことに驚いています。 'File.NullDevice'のようなものです。 –

関連する問題