How to use Pipe Symbol through exec in Java [duplicate]

I am using the following code to get the details of all process running in the system:

Process p = Runtime.getRuntime().exec("ps aux");
BufferedReader stdInput = new BufferedReader(new 
             InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new 
             InputStreamReader(p.getErrorStream()));

I want to filter ps aux down with the pipe symbol so I use this:

Process p = Runtime.getRuntime().exec("ps aux | grep java");

It goes to the ErrorStream. Later I noticed the Pipe Symbol (|) is used as Bitwise inclusive OR operator in Java. So I used backslash in front of pipe symbol as shown below:

Process p = Runtime.getRuntime().exec("ps aux \\| grep java"); 

But again it goes to the ErrorStream. How can I run ps aux | grep java through exec in Java?


Well, if you want to use pipes in the Process you exec, then you need to start a shell like bash, and give ps and grep on the command line to that shell:

bash -c "echo $PATH"

Try this to understand what I mean, then use this:

bash -c "ps axu | grep PATTERN"

to understand how you need to set up your java.runtime.Process.

I did not try it but I assume this:

Process p = Runtime.getRuntime().exec(new String[] { "bash", "-c", "ps axu | grep PATTERN" });

Hope that helps ;D


The pipe is a shell feature - you're not using a shell, you're exec'ing a process (ps).

But really, why would you want to do this? What you're saying is:

"execute ps, then pipe its output to another program (grep) and have it extract what I need"

You just need to extract what you want from the output of ps. Use a Matcher and only pay attention to the lines that include java from your InputStream

http://download.oracle.com/javase/6/docs/api/java/util/regex/Matcher.html


  1. You need to separate the command from its arguments when calling exec, eg .exec(new String[] { "ps", "aux" }) (not exec("ps aux")). When you need to pass arguments, you need to invoke the String[] version - the first element of the String[] is the command, the rest are the arguments.

  2. You need to send the contents of the output stream of the first command to the input stream of the second command. I used Apache commons IOUtils to do this with ease.

  3. You must close the input stream of the grep call, otherwise it will hang waiting for the end of input.

With these changes in place, this code does what you want:

import org.apache.commons.io.IOUtils;

public static void main(String[] args) throws Exception
{
    Process p1 = Runtime.getRuntime().exec(new String[] { "ps", "aux" });
    InputStream input = p1.getInputStream();
    Process p2 = Runtime.getRuntime().exec(new String[] { "grep", "java" });
    OutputStream output = p2.getOutputStream();
    IOUtils.copy(input, output);
    output.close(); // signals grep to finish
    List<String> result = IOUtils.readLines(p2.getInputStream());
    System.out.println(result);
}