Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java exec() does not return expected result of pipes' connected commands

I'm calling command line programs connected by pipes. All this works on Linux for sure.

My method:

protected String execCommand(String command) throws IOException {
    String line = null;
    if (command.length() > 0) {
        Process child = Runtime.getRuntime().exec(command);
        InputStream lsOut = child.getInputStream();
        InputStreamReader r = new InputStreamReader(lsOut);
        BufferedReader in = new BufferedReader(r);

        String readline = null;
        while ((readline = in.readLine()) != null) {
            line = line + readline;
        }
    }

    return line;
}

If I'm calling some cat file | grep asd, I'm getting the expected result. But not all commands works correctly. For example with this:

cat /proc/cpuinfo | wc -l

or this:

cat /proc/cpuinfo | grep "model name" | head -n 1 | awk -F":" '{print substr($2, 2, length($2))}

the method will return null. I'm guessing this problem depends on output formatting commands like head, tail, wc, etc. How I can work around this problem and get the final result of the output?

like image 454
Pawka Avatar asked Jan 18 '10 20:01

Pawka


3 Answers

The pipe (like redirection, or >) is a function of the shell, and so execing directly from Java won't work. You need to do something like:

/bin/sh -c "your | piped | commands | here"

which executes a shell process with the command line (including pipes) specified after the -c (in quotes).

Note also that you have to consume stdout and stderr concurrently, otherwise your spawned process will block waiting for your process to consume the output (or errors). More info here.

like image 178
Brian Agnew Avatar answered Oct 11 '22 20:10

Brian Agnew


Everyone who uses Runtime.exec should read this.

like image 39
duffymo Avatar answered Oct 11 '22 19:10

duffymo


It might be a good idea to check the error stream of the Process as well.

like image 35
matt b Avatar answered Oct 11 '22 21:10

matt b