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

Vin*_*esh 8 java pipe exec

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

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

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

Process p = Runtime.getRuntime().exec("ps aux | grep java");
Run Code Online (Sandbox Code Playgroud)

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

Process p = Runtime.getRuntime().exec("ps aux \\| grep java"); 
Run Code Online (Sandbox Code Playgroud)

但它再次进入ErrorStream.我如何ps aux | grep java在Java中运行exec?

Ang*_*ere 16

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

bash -c "echo $PATH"
Run Code Online (Sandbox Code Playgroud)

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

bash -c "ps axu | grep PATTERN"
Run Code Online (Sandbox Code Playgroud)

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

我没试过,但我假设这个:

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

希望有所帮助; D.


Bri*_*ach 5

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

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

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

你只需要从输出中提取你想要的东西ps.使用a Matcher并且只注意包含java你的行InputStream

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

  • 你真的不应该花费更多的时间来处理使用`匹配器'的行,而不是需要执行另一个进程并将`ps`的输出传递给它的shell.那就是说...我认为*你可以执行一个shell,例如`/ bin/bash -c ps aux | grep java` (2认同)

Boh*_*ian 5

  1. 调用exec时需要将命令与其参数分开,例如.exec(new String[] { "ps", "aux" })(not 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);
}
Run Code Online (Sandbox Code Playgroud)

  • 这是单线程时的死锁危险吗?可以从commons-exec使用`PumpStreamHandler`. (2认同)