2011-01-12 8 views
1

私は別のプロセスでコマンドを実行すると、例えばそのJavaDocの状態Runtime.getRuntime().exec(...)方法、使用して:外部プロセスから不要なストリームをどうすればいいですか?

Executes the specified command and arguments in a separate process. 

を私はプロセスが生きることを知って、このプロセスからのストリームを行うには何が必要ですJavaプログラムが存在するまで? (これは詳細ですが、Javaプログラムはこのプロセスを強制終了させ、プロセス自体には、JavaプログラムがJavaプログラムを実行していないことを認識すると、安全性が組み込まれています)。

すべてのエラーメッセージとstdoutが/ dev/nullにリダイレクトされ、すべての通信がファイル/ソケット/その他を使用して行われているためなど、このプロセスで出力がまったく生成されないと考えると、何が必要ですか入力ストリームで?

stdout/stderrを読み込もうとすると、1つ(または2つ)のJavaスレッドを何も実行しないでください。

stdout/stderrがまったく生成されないJavaプログラムから生成された、長寿命の外部プロセスを扱う正しい方法は何ですか?

EDIT

基本的に私はを/ dev/nullにすべてをリダイレクトするようにしてくださいになり、別のシェルスクリプトでシェルスクリプトを包みます。私の "outter"シェルスクリプト(すべてを/ dev/nullにリダイレクトするもの)がまだstdoutまたはstderrに何かを生成している場合、私のUn * xが非準拠であると確信しています。しかし、私はアプリのライフサイクル中に何かのためにスレッドを稼働させなければならないと考えていることに気付いています。本当に心を揺さぶる。

答えて

1

すべてがあなたの言うとおりであれば、おそらく無視することができます。

しかし、まれに物事がきれいに機能します。ちょうどの場合に、stdout/stderrを引っ張るために1つのスレッドを生成することは、長期的には価値があるかもしれません。ある日、それは失敗し、実際に何かを出す、あなたが何が出てきたかを知る必要があった日です。 1つまたは2つのスレッド(私はそれがただ1つでできると思います)は大きなオーバーヘッドにはなりません。特にあなたが正しい場合、それらの流れから何も出てこない。

+0

興味深い。私は自分の質問を編集します...基本的には、すべてを*/dev/null *にリダイレクトする別のシェルスクリプトでシェルスクリプトをラップします。 * outterシェルスクリプト(すべて*/dev/null *にリダイレクトするスクリプト)が* stdout *や* stderr *上に何かを生成しても、Un * xが非準拠であることは確かです。 – SyntaxT3rr0r

+0

@ SyntaxT3rr0r - わかりました。私はそれらの編集的な人々のほんの一人です。 :)私は余分なスレッドがおそらく不要であることに同意します。 – rfeak

1

あなたが興味を持っていない場合、プロセスの入力と出力を処理する正しい方法は、それらをすぐに閉じることです。子プロセスがその後stdinまたはstdoutでそれぞれreadまたはwriteを呼び出そうとすると、IOExceptionがスローされます。それが読み書きできないという事実に対処するのは、子プロセスの責任です。

ほとんどのプロセスは、書き込みできず、黙って破棄して書き込むことができないという事実を無視します。これは、System.outがPrintWriterであるJavaでは当てはまります。したがって、stdoutによってスローされたIOExceptionは無視されます。これは、出力を/ dev/nullにリダイレクトするとどうなるでしょうか?すべての出力は黙って破棄されます。

プロセスでAPIを読んだようですが、独自の書き込みや読み取りを行うことが予想される場合は、プロセスを読み書きすることが重要です。しかし、私は繰り返し述べますが、一部のOSは(特に)stdout用に非常に限られたバッファしか割り当てていないので、このバッファをいっぱいにしないことが重要です。これは、子プロセスの出力を速やかに読み込むこと、またはプロセスの出力を必要としないこと、および保持されているリソースを解放できることをOSに通知することを意味し、stdoutへの書き込みを試みたり、リソースが利用できるようになるまでぶら下げるだけです)。

+0

答えに感謝します...私はそれを読んだだけではありません。私はそれを読んだことがあり、何年も前からJavaから外部プロセスを起動したときに、私は一貫してb ****に噛まれてきました。だから私はかなり根本的なアプローチをしています。実際に私はちょうど何か他のものを考えました:私の "outter"スクリプトは "nohup"を行い、ハングアップ/殺すことのない別のスクリプトと、そのストリームにJavaと何も関係ない**スクリプトを生成します。したがって、Javaから私は内部スクリプトがJavaにとって不可視であることを知っているので、しばらくしてから "outter"スクリプトを読み書き/クローズすることができます:) – SyntaxT3rr0r

+0

子プロセスは必ずしもJava VMではないので、必ずIOExceptionをスローすることはできません。例えば、 'SIGPIPE'を受け取るかもしれません。 – finnw

+0

@finnwあなたのポイントは分かりません。 JVMは同じSIGPIPEを受け取り、IOExceptionを受け取るとIOExceptionをスローします。 SIGPIPEを受け取ったときのプロセスはそれに従います。 grepのようなプログラムはSIGPIPEを受け取れば終了しますが、firefoxやvlcは気にしません。 – Dunes

関連する問題