我正在调用通过pipe道连接的命令行程序。 所有这些都可以在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; }
如果我打电话给一些猫文件| 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。 我猜这个问题取决于输出格式化命令,如头 , 尾巴 , 厕所等我怎样才能解决这个问题,并得到最终的结果?
管道(如重定向,或>
)是shell的一个函数,所以直接从Java中直接执行是行不通的。 您需要执行以下操作:
/bin/sh -c "your | piped | commands | here"
它使用-c
(在引号中)之后指定的命令行(包括管道)执行shell进程。
还要注意,你必须同时使用stdout
和stderr
,否则你的产生的进程会阻塞等待你的进程使用输出(或错误)。 更多信息在这里 。
每个使用Runtime.exec的人都应该阅读这个 。
仍然没有找到适当的解决方案来执行与Runtime.exec管道命令,但找到了一种解决方法。 我只是写了这些脚本分开bash文件。 然后Runtime.exec调用这些bash脚本并获得预期的结果。
检查Process的错误流也是一个好主意。
这个快速而肮脏的事情是:
command = "/bin/sh -c '" + command.replaceAll("'", "'\''") + "'"
通常情况下,你将不得不注意shell注入(即有人偷偷"; rm -rf /;"
到命令中)。 但是这只是一个问题,如果命令的一部分可以从其他用户输入提供。
缓慢而痛苦的做法是自己用Java做Bash。 如果你顺着这条路走,你会发现Bash给你的所有美妙的东西都不能从Process.exec
直接获得(管道,重定向,复合命令,可变扩展,算术评估…)。
|
的命令 字符。 一定要注意||
并引用字符串。 Process
。 Thread
,读取一个命令的输出并将其写入下一个命令的输入。 可能有点晚了,但对于其他人寻找解决方案,试试这个…
String[] cmd = { "/bin/sh", "-c", "cat /proc/cpuinfo | wc -l" }; Process process = Runtime.getRuntime().exec(cmd);
祝一切顺利..