簡體   English   中英

通過Runtime.getRuntime()。exec運行linux命令時出錯

[英]Error while running linux command through Runtime.getRuntime().exec

我正在嘗試在Java程序中運行以下命令

Runtime.getRuntime().exec("ls -lrt service/logs/post/level2.log | awk '{print $9}'");
or
Runtime.getRuntime().exec("ls -lrt service/logs/post/level2* | awk '{print $9}'");

它給了我以下錯誤

ls: 0653-341 The file | does not exist.
ls: 0653-341 The file awk does not exist.
ls: 0653-341 The file '{print does not exist.
ls: 0653-341 The file $9}' does not exist.

請幫助我

管道是基於外殼的構造,不是實際的可運行命令。 我看到有兩種方法可以做到這一點:

  1. 在Java中自己進行管道傳輸。 首先調用ls命令,獲取其OutputStream的句柄,然后調用awk將第一個Process的輸出連接到第二個Process的輸入流。
  2. 直接從Java調用bash shell,將整個命令作為bash的-c參數的參數傳遞。 這樣,所有管道均單個過程中完成。

至於基於令牌的錯誤,您應該使用字符串數組來調用這些命令。 每個元素代表命令行的標記。 因此,例如:

Runtime.getRuntime().exec(new String[] { "ls", "-lrt", "service/logs/post/level2.log" });

為了調用ls命令。 在這種情況下,我認為這不是絕對必要的,但是它將用於awk命令,因為Java對特定於shell的引用規則一無所知,因此默認情況下,在空格字符上標記單字符串輸入。 這就是為什么將awk腳本一分為二的原因。


編輯 (針對評論):在第一個選項中,我的意思是簡單地說,您可以使用Java自己在兩個進程之間傳遞輸出。

想象一下,如果您已經這樣創建了一個流程:

Process ls = Runtime.getRuntime().exec("ls -lrt service/logs/post/level2.log");

現在,此過程將運行並生成一些輸出(我們知道這將是描述該文件的一行)。 我們可以像這樣獲取輸出:

InputStream lsOut = ls.getInputStream();

現在,我們要運行該awk流程:

Process awk = Runtime.getRuntime().exec(new String[] { "awk", "{print $9}"});

當然,awk進程會在等待輸入的時刻,因為它知道它將從stdin中讀取。 因此,我們獲取了將要使用的輸入流:

OutputStream awkIn = awk.getOutputStream();

現在,管道位-我們讀取ls命令的輸出,並將其傳遞給awk的輸入:

// TODO add buffering, error handling, probably run this in a separate thread
int datum = lsOut.read();
while (datum != -1)
{
    awkIn.write(datum);
    datum = lsOut.read();
}

這將讀取ls的輸出(為簡單起見,逐個字節,使用字節數組緩沖區會更快,但我試圖簡單地說明這個概念)並將其寫入awk的輸入。

然后,只需閱讀awk流程的輸出並按您認為合適的方式處理它即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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