Search code examples
javaprocessbuilder

Running another program but leaving stdout/stderr alone


I need, from a Java program, to run another program (a plain commandline executable), wait for it to finish, check the exit code. This can be done easily enough:

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("process exit value: " + e);
    System.exit(e);
  }
}

However, stdout/stderr from that program, go into the bit bucket. Is there a way to change things so that stdout/stderr appear on the console as normal, the way they would if the program was called from a shell script?

I am not looking for how to capture stdout/stderr. I know how to do that; it involves some moderately messy multithreaded code, and a delay before the resulting output can be dumped to the console. I'm hoping instead that there is a simple way to tell the relevant machinery to just leave stdout/stderr alone to output to console as they normally would.


Solution

  • You can use redirectOutput for stdout, and the similar call redirectError for stderr:

    builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
    builder.redirectError(ProcessBuilder.Redirect.INHERIT);
    

    As @Abra points out, the inheritIO() method is a convenience for these two calls as well as the stdin equivalent.