2010-06-22 20 views
1

我想在我的Java程序出錯()。exec的

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. 

運行以下命令請幫我

回答

9

管道是基於shell的構造,而不是實際的可運行命令。有兩個選項可以做到這一點,因爲我看到它:

  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過程的輸出並按照您認爲合適的方式處理它。

+0

對不起,親愛的,我無法忍受一點善意的幫助。 – user369151 2010-06-22 12:39:54

+0

我需要了解第一個過程輸出到第二個過程輸入流的部分。 – user369151 2010-06-22 12:41:29

+0

@Andrzej Doyle:只是想檢查一下:執行Runtime.getRuntime().exec(「file.sh」)是否可以工作或甚至沒有? – Xorty 2010-06-22 12:41:43