我使用以下代码来获取系统中运行的所有进程的详细信息:
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
?
答案 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)
调用exec时需要将命令与其参数分开,例如.exec(new String[] { "ps", "aux" })
( not exec("ps aux")
)。当你需要传递参数时,你需要调用String []版本 - String[]
的第一个元素是命令,其余的是参数。
您需要将第一个命令的输出流的内容发送到第二个命令的输入流。我使用Apache commons IOUtils轻松完成此操作。
您必须关闭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);
}
答案 3 :(得分:0)
很抱歉,我不知道如何正确地将结果从一个命令传递到另一个命令,但如果你想要的只是Java进程,那么JDK会附带一个名为jps
的程序。试试这个:
jps -l