[英]Java exec() does not return expected result of pipes' connected commands
我正在調用通過管道連接的命令行程序。 所有這些都可以在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。 我猜這個問題取決於輸出格式化命令,如head , tail , wc等。我如何解決這個問題並獲得輸出的最終結果?
管道(如重定向或>
)是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);
祝一切順利..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.