我正在调用通过管道连接的命令行程序。所有这些都可以在Linux上运行。
我的方法:
protected String execCommand(String command) throws IOException {
String line = null;
if (command.length() > 0) {
Process child = Runtime.getRuntime().exec(command);
InputStream lsOut = child.getInputStream();
InputStreamReader r = new InputStreamReader(lsOut);
BufferedReader in = new BufferedReader(r);
String readline = null;
while ((readline = in.readLine()) != null) {
line = line + readline;
}
}
return line;
}
如果我正在调用一些 cat文件| grep asd ,我得到了预期的结果。但并非所有命令都能正常工作。例如:
cat /proc/cpuinfo | wc -l
或者这个:
cat /proc/cpuinfo | grep "model name" | head -n 1 | awk -F":" '{print substr($2, 2, length($2))}
该方法将返回null。我猜这个问题取决于输出格式化命令,如 head , tail , wc 等。我如何解决这个问题并得到输出的最终结果?
答案 0 :(得分:8)
管道(如重定向或>
)是shell的一个功能,因此直接从Java执行将不起作用。您需要执行以下操作:
/bin/sh -c "your | piped | commands | here"
使用-c
(引号)后指定的命令行(包括管道)执行shell进程。
另请注意,您必须同时使用stdout
和stderr
,否则您的衍生进程将阻止等待您的进程使用输出(或错误)。更多信息here。
答案 1 :(得分:2)
使用Runtime.exec的每个人都应该阅读this。
答案 2 :(得分:2)
仍未找到使用Runtime.exec执行管道命令的正确解决方案,但找到了解决方法。我只是编写这些脚本来分隔bash文件。然后Runtime.exec调用这些bash脚本并获得预期的结果。
答案 3 :(得分:1)
同样检查the error stream of the Process可能是个好主意。
答案 4 :(得分:0)
快速而肮脏的事情将是:
command = "/bin/sh -c '" + command.replaceAll("'", "'\''") + "'"
通常情况下,你必须注意shell注入(即有人将"; rm -rf /;"
偷偷带入命令中)。但是,如果可以从其他一些用户输入提供部分命令,那只是一个问题。
缓慢而痛苦的方法是用Java自己做Bash管道。如果你走这条路,你会发现Process.exec
无法直接获得的所有wonderful things that Bash gives you(管道,重定向,复合命令,变量扩展,算术评估......)。
|
个字符的命令。请务必留意||
和引用的字符串。Process
。Thread
来读取一个命令的输出并将其写入下一个命令的输入。答案 5 :(得分:0)
可能有点太晚了但是对于寻找解决方案的其他人来说,试试这个...
String[] cmd = {
"/bin/sh",
"-c",
"cat /proc/cpuinfo | wc -l"
};
Process process = Runtime.getRuntime().exec(cmd);
一切顺利......