簡體   English   中英

Java exec()不返回管道連接命令的預期結果

[英]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。 我猜這個問題取決於輸出格式化命令,如headtailwc等。我如何解決這個問題並獲得輸出的最終結果?

管道(如重定向或> )是shell的一個功能,因此直接從Java執行將不起作用。 你需要做一些事情:

/bin/sh -c "your | piped | commands | here"

它使用在-c (引號)后指定的命令行(包括管道)執行shell進程。

還要注意的是,你必須消耗stdoutstderr 的同時 ,否則你的衍生進程將阻止等待你的過程中要消耗的輸出(或錯誤)。 更多信息在這里

使用Runtime.exec的每個人都應該閱讀此內容

仍未找到使用Runtime.exec執行管道命令的正確解決方案,但找到了解決方法。 我只是編寫這些腳本來分隔bash文件。 然后Runtime.exec調用這些bash腳本並獲得預期的結果。

檢查Process的錯誤流也許是一個好主意。

快速而骯臟的事情是:

command = "/bin/sh -c '" + command.replaceAll("'", "'\''") + "'"

通常情況下,你必須注意shell注入(即有人偷偷摸摸"; rm -rf /;"進入命令)。 但是,如果可以從其他一些用戶輸入提供部分命令,那么這只是一個問題。

緩慢而痛苦的方法是用Java自己做Bash管道。 如果你沿着這條路走下去,你會發現Bash為你提供的所有不能直接從Process.exec (管道,重定向,復合命令,變量擴展,算術評估......)。

  1. 解析|的命令 字符。 一定要注意|| 和引用的字符串。
  2. 為每個管道命令生成一個新Process
  3. 創建從一個命令讀取輸出的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM