La respuesta aceptada es erróneo.
Uno tiene que leer la salida continuamente, mientras espera que el comando termine. De lo contrario, si el comando produce suficiente salida para completar un búfer de salida, el comando se bloqueará, esperando que se consuma el búfer, lo que nunca ocurre. Entonces te encuentras en un punto muerto.
El siguiente ejemplo muestra tanto stdout como stderr de forma continua, mientras se supervisa un estado de comando. Se basa en el official JSch exec.java
example (solo agrega una lectura de stderr).
ChannelExec channel = (ChannelExec)session.openChannel("exec");
channel.setCommand(
"for((i=1;i<=10000;i+=2)); do echo \"Long output - $i\"; done ; " +
"echo error output >&2");
InputStream commandOutput = channel.getExtInputStream();
StringBuilder outputBuffer = new StringBuilder();
StringBuilder errorBuffer = new StringBuilder();
InputStream in = channel.getInputStream();
InputStream err = channel.getExtInputStream();
channel.connect();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) break;
outputBuffer.append(new String(tmp, 0, i));
}
while (err.available() > 0) {
int i = err.read(tmp, 0, 1024);
if (i < 0) break;
errorBuffer.append(new String(tmp, 0, i));
}
if (channel.isClosed()) {
if ((in.available() > 0) || (err.available() > 0)) continue;
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}
System.out.println("output: " + outputBuffer.toString());
System.out.println("error: " + errorBuffer.toString());
channel.disconnect();
Si agrega while (!channel.isClosed()) {}
después de la channel.connect();
, se verá que con una cantidad suficientemente grande i
en la cáscara for
bucle (10000 es suficiente con en mi entorno), el bucle no termina nunca.
La suspensión se debió en realidad a algunas comillas no balanceadas en el comando. –
¿Podría agregar su solución como respuesta en lugar de un comentario? –