Vous voulez le astuce ?
Ne démarrez pas votre processus à partir de ProcessBuilder.start() . N'essayez pas de jouer avec la redirection/consommation de flux depuis Java (surtout si vous ne vous en souciez pas ; )
Utilisez ProcessBuilder.start() pour lancer un petit script shell qui engloutit tous les flux d'entrée/sortie.
Quelque chose comme ça :
#!/bin/bash
nohup $1 >/dev/null 2>error.log &
C'est-à-dire :si vous ne vous souciez pas de stdout et que vous souhaitez toujours enregistrer stderr (n'est-ce pas ?) dans un fichier (error.log ici).
Si vous ne vous souciez même pas de stderr, redirigez-le simplement vers stdout :
#!/bin/bash
nohup $1 >/dev/null 2>1 &
Et vous appelez ce petit script de Java, en lui donnant comme argument le nom du processus que vous souhaitez exécuter.
Si un processus exécuté sous Linux qui redirige à la fois stdout et stderr vers /dev/null produit toujours quelque chose alors vous avez une installation Linux cassée et non conforme ;)
En d'autres termes :le Just Works [TM] ci-dessus et débarrassez-vous du problème "vous devez consommer les flux dans ceci et dans cet ordre bla bla bla Java-spécifique non-sens" .
Si le processus écrit dans stderr
ou stdout
, et vous ne le lisez pas - il va simplement "se bloquer", bloquant lors de l'écriture dans stdout/err
. Soit rediriger stdout/err
à /dev/null
en utilisant un shell ou une fusion stdout/err
avec redirectErrorStream(true) et génère un autre thread qui lit à partir de stdout
du processus
Le thread exécutant le processus peut se bloquer s'il ne gère pas la sortie. Cela peut être fait en créant un nouveau thread qui lit la sortie du processus.
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();