Anda menginginkan itu trik?
Jangan memulai proses Anda dari ProcessBuilder.start() . Jangan mencoba mengotak-atik pengalihan aliran/konsumsi dari Java (terutama jika Anda tidak peduli tentang hal itu; )
Gunakan ProcessBuilder.start() untuk memulai skrip shell kecil yang melahap semua aliran input/output.
Sesuatu seperti itu:
#!/bin/bash
nohup $1 >/dev/null 2>error.log &
Yaitu:jika Anda tidak peduli dengan stdout dan masih ingin mencatat stderr (bukan?) ke file (error.log di sini).
Jika Anda bahkan tidak peduli dengan stderr, arahkan saja ke stdout:
#!/bin/bash
nohup $1 >/dev/null 2>1 &
Dan Anda memanggil skrip kecil dari Java itu, memberikannya sebagai argumen nama proses yang ingin Anda jalankan.
Jika proses yang berjalan di Linux yang mengarahkan stdout dan stderr ke /dev/null masih menghasilkan apa saja maka Anda memiliki instalasi Linux yang rusak, tidak sesuai,;)
Dengan kata lain:Just Works [TM] di atas dan singkirkan "Anda perlu mengonsumsi aliran dalam urutan ini dan itu bla bla bla non-sense khusus Java" .
Jika proses menulis ke stderr
atau stdout
, dan Anda tidak membacanya - itu hanya akan "hang" , memblokir saat menulis ke stdout/err
. Redirect stdout/err
ke /dev/null
menggunakan shell atau menggabungkan stdout/err
dengan redirectErrorStream(true) dan memunculkan utas lain yang membaca dari stdout
dari proses
Utas yang menjalankan proses dapat diblokir jika tidak menangani keluaran. Ini dapat dilakukan dengan menelurkan utas baru yang membaca hasil proses.
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();