2011-08-29 58 views
8
使用管道符号

我使用下面的代码来获取系统中运行的所有进程的详细信息:如何通过EXEC在Java中

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中的按位包含OR运算符。所以,我在管道符号前面使用反斜杠,如下图所示:

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

但同样它去ErrorStream。我如何通过Java中的exec运行ps aux | grep java

+0

只是为了澄清,该位或运算符'|'是不是字符串中的解释,所以你不应该需要逃避它。 –

回答

5

管道是一个壳特征 - 你不使用外壳,你exec'ing过程(ps)。

但是真的,你为什么要这么做?你的意思是:

“执行PS,然后通过管道将其输出到另一个程序(grep的),并把它提取我需要什么”

你只需要提取你想要的东西从ps输出。使用Matcher,只注重线,其中包括javaInputStream

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

+0

感谢您的回复。当我使用Runtime.getRuntime()。exec(“ps aux”)时,需要花费时间来处理InputStream中的所有行。所以我认为Runtime.getRuntime()。exec(“ps aux | grep java”)只是我的工作。如果我再次选择Matcher,则需要花费时间来处理线条。有没有其他的方式来使用管道? – Vinesh

+2

实际上你不应该花更多的时间来使用'Matcher'来处理这些行,而不是使用另一个进程来执行'ps'的输出。这就是说...我认为你可以执行一个shell,比如'/ bin/bash -c ps aux | grep java' –

0

对不起,我不知道如何正确地将结果从一个命令传递到另一个命令,但如果您只想要Java过程,那么JDK附带了一个名为jps的程序,它可以完成此操作。试试这个:

jps -l 
+0

感谢您的回复。我尝试了这个命令,它产生了包含PID,进程名称的列表。我想要获得PID%CPU%MEM VSZ RSS TTY&COMMAND。 – Vinesh

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

  2. 您需要将第一个命令的输出流的内容发送到第二个命令的输入流。我用Apache commons IOUtils轻松做到这一点。

  3. 您必须关闭grep调用的输入流,否则它将挂起等待输入结束。

随着这些变化的地方,这个代码你想要做什么:

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

单线程是否会导致死锁危险?可以使用commons-exec中的'PumpStreamHandler'。 – msandiford

+0

公平的评论。我试图尽可能简单地说明重要的部分。警告:在单线程环境中可能会死锁。 – Bohemian

16

好吧,如果你想使用过程中管你EXEC,那么你就需要开始喜欢的bash外壳,并给予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

+0

嘿,这很好!谢谢! – Erhannis

+0

这不适合我...阅读[this](http://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep)后,我终于决定使用pgrep来代替的grep – boly38