如何在Java中通过exec使用Pipe符号

时间:2011-08-29 05:47:19

标签: java exec pipe

我使用以下代码来获取系统中运行的所有进程的详细信息:

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

我想用管道符号过滤ps aux,所以我使用它:

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

它转到ErrorStream。后来我注意到管道符号(|)在Java中用作Bitwise包含OR运算符。所以我在管道符号前面使用了反斜杠,如下所示:

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

但它再次进入ErrorStream。如何通过Java中的exec运行ps aux | grep java

4 个答案:

答案 0 :(得分:16)

好吧,如果你想在你的exec中使用管道,那么你需要像bash一样启动一个shell,并在命令行上给ps和grep:

bash -c "echo $PATH"

试试这个来理解我的意思,然后使用它:

bash -c "ps axu | grep PATTERN"

了解如何设置java.runtime.Process。

我没有尝试,但我认为:

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

希望有所帮助; D

答案 1 :(得分:5)

管道是一个shell功能 - 你没有使用shell,你正在执行一个进程(ps)。

但实际上,你为什么要这样做?你在说什么:

“执行ps,然后将其输出传递给另一个程序(grep)并让它提取我需要的东西”

您只需要从ps的输出中提取您想要的内容。使用Matcher,只关注java

中包含InputStream的行

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

答案 2 :(得分:5)

  1. 调用exec时需要将命令与其参数分开,例如.exec(new String[] { "ps", "aux" }) not exec("ps aux"))。当你需要传递参数时,你需要调用String []版本 - String[]的第一个元素是命令,其余的是参数。

  2. 您需要将第一个命令的输出流的内容发送到第二个命令的输入流。我使用Apache commons IOUtils轻松完成此操作。

  3. 您必须关闭grep来电的输入流,否则会等待输入结束。

  4. 通过这些更改,此代码可以满足您的需求:

    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);
    }
    

答案 3 :(得分:0)

很抱歉,我不知道如何正确地将结果从一个命令传递到另一个命令,但如果你想要的只是Java进程,那么JDK会附带一个名为jps的程序。试试这个:

jps -l