一个人不只是简单地进入 ProcessBuilder
One does not simply grep into ProcessBuilder
有谁知道如何将 linux grep 与 java ProcessBuilder 一起使用?为什么这段代码 return 应该是空字符串 return "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
尽管出于某种原因它是红色字体。那我做错了什么?
what am I doing wrong?
很明显的东西。
您希望 execve()
理解 shell 结构吗?号
嗯,您也不应期望 ProcessBuilder
理解这些内容。虽然它不像execve()
那么低级,但它足够低级到命令的参数是"raw"。因此,在您的命令中,<<<"sing"
作为参数传递给 grep
;这意味着 grep
将其视为要读取的文件。
记住这一点:您在 shell 中键入的内容由 shell 解释; a ProcessBuilder
不会 使用 shell 来执行其进程,execve()
也不会。反过来,这意味着您 不能 使用 shell 结构。
如果您想要 grep
,则必须 feed your process' input 使用您想要的文字。但是,为什么在 Java 具有内置正则表达式引擎时使用 grep
是另一个问题,当然。
至于:
although it is in red font for some reason
它只是来自 grep
命令的文本装饰(好吧,至少是 GNU grep);请参阅其联机帮助页和 --color
选项。简而言之,在您的情况下,它检测到您的 tty 具有更改文本颜色的功能,并使用它来装饰匹配的文本。
尝试并:
echo foobar | grep foo
它会以红色回显 foobar
和 foo
。
您实际上可以 运行 使用 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
有谁知道如何将 linux grep 与 java ProcessBuilder 一起使用?为什么这段代码 return 应该是空字符串 return "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
尽管出于某种原因它是红色字体。那我做错了什么?
what am I doing wrong?
很明显的东西。
您希望 execve()
理解 shell 结构吗?号
嗯,您也不应期望 ProcessBuilder
理解这些内容。虽然它不像execve()
那么低级,但它足够低级到命令的参数是"raw"。因此,在您的命令中,<<<"sing"
作为参数传递给 grep
;这意味着 grep
将其视为要读取的文件。
记住这一点:您在 shell 中键入的内容由 shell 解释; a ProcessBuilder
不会 使用 shell 来执行其进程,execve()
也不会。反过来,这意味着您 不能 使用 shell 结构。
如果您想要 grep
,则必须 feed your process' input 使用您想要的文字。但是,为什么在 Java 具有内置正则表达式引擎时使用 grep
是另一个问题,当然。
至于:
although it is in red font for some reason
它只是来自 grep
命令的文本装饰(好吧,至少是 GNU grep);请参阅其联机帮助页和 --color
选项。简而言之,在您的情况下,它检测到您的 tty 具有更改文本颜色的功能,并使用它来装饰匹配的文本。
尝试并:
echo foobar | grep foo
它会以红色回显 foobar
和 foo
。
您实际上可以 运行 使用 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