一个不仅仅是grep到ProcessBuilder

时间:2015-01-30 21:11:10

标签: java shell grep processbuilder herestring

有没有人知道如何在java ProcessBuilder中使用linux grep?为什么这个代码在返回时会返回一个空字符串" 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

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

2 个答案:

答案 0 :(得分:3)

  

我做错了什么?

非常明显的东西。

您是否期望execve()能够理解shell构造?否。

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

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

如果您想要grep,则必须feed your process' input添加所需的文字。但是,当Java具有内置正则表达式引擎时,为什么使用grep是另一个问题,当然。

至于:

  

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

它只是来自grep命令的文本修饰(至少是GNU grep);请参阅其联机帮助页和--color选项。简而言之,在您的情况下,它已检测到您的tty具有更改文本颜色的功能,并使用它来装饰匹配的文本。

尝试并:

echo foobar | grep foo

它将foobarfoo红色回显。

答案 1 :(得分:1)

您实际上可以使用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