欲しいのは トリック?
ProcessBuilder.start() からプロセスを開始しないでください . Java からのストリームのリダイレクト/消費を台無しにしようとしないでください (特に、それについて何も言わない場合は; )
ProcessBuilder.start() を使用 すべての入力/出力ストリームをむさぼり食う小さなシェル スクリプトを開始します。
そのようなもの:
#!/bin/bash
nohup $1 >/dev/null 2>error.log &
つまり、標準出力を気にせず、標準エラー出力をファイル (error.log) に記録したい場合 (そうですか?)
stderr を気にしない場合は、stdout にリダイレクトしてください:
#!/bin/bash
nohup $1 >/dev/null 2>1 &
そして、実行したいプロセスの名前を引数として渡して、Java からその小さなスクリプトを呼び出します。
stdout と stderr の両方を /dev/null にリダイレクトしている Linux で実行されているプロセスが、依然として 何か を生成する場合 その場合、壊れた、非準拠の Linux インストールがあります;)
言い換えれば、上記の Just Works [TM] は問題を取り除きます 「これとその順序でストリームを消費する必要があります bla bla bla Java 固有のナンセンス」 .
プロセスが stderr
に書き込む場合 または stdout
、そしてあなたはそれを読んでいません-それはただ「ハング」し、 stdout/err
への書き込み時にブロックします . stdout/err
をリダイレクトするか /dev/null
まで シェルまたはマージ stdout/err
を使用する redirectErrorStream(true) を使用して、stdout
から読み取る別のスレッドを生成します プロセスの
プロセスを実行しているスレッドは、出力を処理しない場合、ブロックされる可能性があります。これは、プロセスの出力を読み取る新しいスレッドを生成することで実行できます。
final ProcessBuilder builder = new ProcessBuilder("script")
.redirectErrorStream(true)
.directory(workDirectory);
final Process process = builder.start();
final StringWriter writer = new StringWriter();
new Thread(new Runnable() {
public void run() {
IOUtils.copy(process.getInputStream(), writer);
}
}).start();
final int exitValue = process.waitFor();
final String processOutput = writer.toString();