2

有谁知道如何将 linux grep 与 java ProcessBuilder 一起使用?为什么这段代码应该返回 "sing" 时返回一个空字符串?

import java.io.*;
import java.util.*;

public class Test2 {

public static void main(String[] args) throws InterruptedException,IOException{
    String line;

    // Initiate grep process.
    ProcessBuilder pb = new ProcessBuilder("grep", "\"sing\"", "<<<\"sing\"");
    Process p = pb.start();
    p.waitFor();

    // Get grep output:     
    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

    StringBuilder builder = new StringBuilder();
    line = null;
    while ( (line = reader.readLine()) != null) {
        builder.append(line);
        builder.append(System.getProperty("line.separator"));
    }
    String result = builder.toString();
    System.out.println(result);     
}
}

我也尝试回显我用这段代码执行的内容:

ProcessBuilder pb = new ProcessBuilder("echo","grep", "\"sing\"", "<<<\"sing\"");

并得到正确的结果:

 grep "sing" <<<"sing"

我终于尝试在 shell 上执行命令并得到:

sing

虽然由于某种原因它是红色字体。那么我做错了什么?

4

2 回答 2

3

我究竟做错了什么?

很明显的东西。

例如,您是否期望execve()理解 shell 结构?不。

好吧,你也不应该期望ProcessBuilder理解这些。虽然它不像 那样低级别execve(),但它的级别足够低,以至于命令的参数是“原始的”。因此,在您的命令中,<<<"sing"按原样作为参数传递给grep; 这意味着grep将其视为要读取的文件。

记住这一点:你在 shell 中输入的内容由 shell 解释;aProcessBuilder 不会使用 shell 来执行它的进程,也不会execve()。反过来,这意味着您不能使用 shell 构造。

如果你愿意,grep你必须用你想要的文本来提供你的过程输入。但是,当 Java 有一个内置的正则表达式引擎时,为什么要使用grep它是另一个问题,当然。

至于:

虽然由于某种原因它是红色字体

它只是grep命令中的文本修饰(好吧,至少是 GNU grep);查看其手册页和--color选项。简而言之,在您的情况下,它检测到您的 tty 具有更改文本颜色的能力,并使用它来装饰匹配的文本。

尝试并:

echo foobar | grep foo

它将foobarfoo红色相呼应。

于 2015-01-30T21:14:33.410 回答
2

您实际上可以使用运行相同的命令,ProcessBuilder但您必须确保它是由bash. 我更喜欢这种实用方法:

public static int runCmd(final String command) {
    Process process=null;
    int ret = 0;
    String[] finalCommand = new String[] { "bash", "-c", command };

    try {
        final ProcessBuilder processBuilder = new ProcessBuilder(finalCommand);
        processBuilder.redirectErrorStream(true);
        process = processBuilder.start();
        ret = process.waitFor();
        // stdout+stderr
        InputStreamReader isr = new InputStreamReader( process.getInputStream() );
        BufferedReader br = new BufferedReader(isr);
        String line;
        while ((line = br.readLine()) != null) {
          System.out.println(line);
        }
        //System.out.println("Program terminated!");
        process.destroy();
        br.close();
        isr.close();
    } 
    catch (IOException|InterruptedException e) { 
        e.printStackTrace(); 
    } 
    return ret;
}

然后将其称为:

runCmd("grep -o \"sing\" <<<\"icansing\"");

它给了我这个输出:

sing
于 2015-01-30T21:21:26.363 回答