es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Ejecutando otro programa pero dejando stdout/stderr intactos.

Necesito, desde un programa Java, ejecutar otro programa (un ejecutable de línea de comandos), esperar a que termine y verificar el código de salida. Esto se puede hacer de manera bastante sencilla:

static void run(String[] cmd) throws IOException, InterruptedException {
  var more = false;
  for (var s : cmd) {
    if (more) System.out.print(' ');
    more = true;
    System.out.print(s);
  }
  System.out.println();
  var builder = new ProcessBuilder(cmd);
  var process = builder.start();
  process.waitFor();
  var e = process.exitValue();
  if (e != 0) {
    System.out.println("valor de salida del proceso: " + e);
    System.exit(e);
  }
}

Sin embargo, la salida estándar/errónea de ese programa se dirige al cubo de basura. ¿Existe alguna forma de cambiar las cosas para que la salida estándar/errónea aparezca en la consola normalmente, como lo harían si el programa fuera llamado desde un script de shell?

No estoy buscando cómo capturar la salida estándar/errónea. Sé cómo hacerlo; implica algún código con múltiples hilos y una espera antes de que la salida resultante se pueda mostrar en la consola. En cambio, espero que haya una forma sencilla de indicarle al mecanismo relevante que simplemente deje la salida estándar/errónea para que se muestre en la consola como lo haría normalmente.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Sí, hay una manera sencilla de redirigir la salida estándar/error del subproceso a la consola. En lugar de utilizar el método ProcessBuilder.start(), utiliza el método ProcessBuilder.inheritIO(). Este método establece las corrientes de entrada, salida y error estándar del subproceso para que sean las mismas que las del proceso Java actual.

    Aquí está el código modificado que utiliza ProcessBuilder.inheritIO():

    static void run(String[] cmd) throws IOException, InterruptedException {
        var more = false;
        for (var s : cmd) {
            if (more) System.out.print(' ');
            more = true;
            System.out.print(s);
        }
        System.out.println();
        var builder = new ProcessBuilder(cmd);
        builder.inheritIO(); // Redirigir stdout/stderr a la consola
        var process = builder.start();
        process.waitFor();
        var e = process.exitValue();
        if (e != 0) {
            System.out.println("valor de salida del proceso: " + e);
            System.exit(e);
        }
    }
    

    Con esta modificación, la salida estándar/error del subproceso será visible en la consola, al igual que cualquier otro ejecutable de línea de comandos llamado desde un script de shell.

Comments are closed.