有没有人知道如何在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
虽然出于某种原因它是红色字体。那么我做错了什么?
答案 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
它将foobar
以foo
红色回显。
答案 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