![](/img/trans.png)
[英]Error executing find command through Runtime.getRuntime().exec()
[英]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.
請幫助我
管道是基於外殼的構造,不是實際的可運行命令。 我看到有兩種方法可以做到這一點:
ls
命令,獲取其OutputStream
的句柄,然后調用awk
將第一個Process
的輸出連接到第二個Process
的輸入流。 -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.