Dónal
Dónal

Reputation: 187529

Redirect process output to stdout

I would like to execute foo.bat from within a Groovy program and have the resulting process' output redirected to stdout. Either a Java or Groovy code example would be fine.

foo.bat can take several minutes to run and generates a lot of output, so I would like to see the output as soon as it is generated, rather than having to wait until the process has completed before seeing all the output at once.

Upvotes: 33

Views: 42549

Answers (7)

Pandurang Patil
Pandurang Patil

Reputation: 1014

It is simple to redirect all your stream to standard output using inheritIO() method. This will print the output to the stdout of the process from which you are running this command.

ProcessBuilder pb = new ProcessBuilder("command", "argument");
pb.directory(new File(<directory from where you want to run the command>));
pb.inheritIO();
Process p = pb.start();
p.waitFor();

There exist other methods too, like as mentioned below. These individual methods will help redirect only required stream.

    pb.redirectInput(Redirect.INHERIT)
    pb.redirectOutput(Redirect.INHERIT)
    pb.redirectError(Redirect.INHERIT)

Upvotes: 73

gMale
gMale

Reputation: 17895

If you're looking to do this with more Groovy and less java, this will print each line as it happens:

def cmd = "./longRunningProcess"

def process = cmd.execute()
process.in.eachLine { line -> println line }

Alternatively, if you want to see both stdout and stderr

def cmd = "./longRunningProcess"

def process = cmd.execute()
process.waitForProcessOutput( System.out, System.err )

Upvotes: 6

yegor256
yegor256

Reputation: 105063

VerboseProcess from jcabi-log can help you:

String output = new VerboseProcess(new ProcessBuilder("foo.bat")).stdout();

Upvotes: 0

Daniel De Le&#243;n
Daniel De Le&#243;n

Reputation: 13649

Asynchronous way to achieve it.

void inputStreamToOutputStream(final InputStream inputStream, final OutputStream out) {
    Thread t = new Thread(new Runnable() {

        public void run() {
            try {
                int d;
                while ((d = inputStream.read()) != -1) {
                    out.write(d);
                }
            } catch (IOException ex) {
                //TODO make a callback on exception.
            }
        }
    });
    t.setDaemon(true);
    t.start();
}

{
    Process p = ...;
    inputStreamToOutputStream(p.getErrorStream(), System.out);
    inputStreamToOutputStream(p.getInputStream(), System.out);
}

Upvotes: 3

jitter
jitter

Reputation: 54605

This uses a class which reads all output the executed program generates and displays it in it's own stdout.

class StreamGobbler extends Thread {
    InputStream is;

    // reads everything from is until empty. 
    StreamGobbler(InputStream is) {
        this.is = is;
    }

    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line=null;
            while ( (line = br.readLine()) != null)
                System.out.println(line);    
        } catch (IOException ioe) {
            ioe.printStackTrace();  
        }
    }
}

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("javac");
//output both stdout and stderr data from proc to stdout of this process
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream());
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream());
errorGobbler.start();
outputGobbler.start();
proc.waitFor();

Upvotes: 37

John Wagenleitner
John Wagenleitner

Reputation: 11035

The following Groovy code will execute foo.bat and send the output to stdout:

println "foo.bat".execute().text

Upvotes: 4

Keith Randall
Keith Randall

Reputation: 23265

Here's something a little simpler if you're just trying to grab the output of a simple command. You'll need to use threads like jitter does if you want to process in parallel or if your command takes stdin or generates stderr.

Use a buffered copy (like this) if you're getting lots of output.

import java.io.*;
public class test {
  static void copy(InputStream in, OutputStream out) throws IOException {
    while (true) {
      int c = in.read();
      if (c == -1) break;
      out.write((char)c);
    }
  }

  public static void main(String[] args) throws IOException, InterruptedException {
    String cmd = "echo foo";
    Process p = Runtime.getRuntime().exec(cmd);
    copy(p.getInputStream(), System.out);
    p.waitFor();
  }
}

Upvotes: 5

Related Questions