2011-12-07 168 views
4

我遇到了一些奇怪的問題。Java - 如何檢查另一個(非Java)進程是否在Linux上運行

我們正在使用Xvfb虛擬桌面管理器,並希望確保它在我繼續之前運行。使用純粹的外殼,我可以很容易地做到這一點:

ps -ef | grep Xvfb | grep -v grep 

而這正是我所需要的,一行包含有關Xvfb proc的信息。接下來,我想將它結合到我的Java程序中,並解析結果並存儲正在運行的Xvfb進程的PID。所以,我想這一點:

String line; 
    try { 
     Process p = Runtime.getRuntime().exec("ps -ef | grep Xvfb | grep -v grep"); 
     BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); 
     while ((line = input.readLine()) != null) 
     { 
     System.out.println(line); 
     } 
    } catch (Exception err) { 
     System.out.println(err); 
    } 

的奇怪的事情是,如果我用「PS -ef」,我得到了巨大的轉儲到我的控制檯進程列表當我運行我的應用程序。但是如果我使用| grep來縮小返回的進程列表,我得到零結果。 input.readLine()每次都會得到空值。

我也曾嘗試:

ps -ef | grep Xvfb | grep -v grep | awk {'print $2'} 

只獲取進程ID。另外,沒有運氣。

有沒有其他人經歷過這個或知道我在做什麼錯?

+1

使用* pgrep *代替ps和2 greps –

回答

5

您試圖使用「|」這是shell特有的管道功能,因此你不能在java進程中執行它。您可以嘗試使用pidof Xvfb來獲取進程ID。

+1

謝謝,完美的工作! – AWT

+1

@ torgis,不客氣!我有一個類似的問題。很高興我的痛苦得到了回報。 – Max

2

當你直接執行命令字符串時,你不會得到一個shell,它是處理管道的shell。所以,你會執行一些像「/ bin/sh -e \」ps -ef | grep Xvfb | grep -v grep \「」

3

也許Runtime.getRuntime().exec()試圖按照它在參數中執行程序。也就是說,它運行程序ps,其參數爲-ef,|grep等。因此,程序失敗,因爲它不知道發生了什麼。

如果你需要運行管道命令,你應該叫殼明確:

Runtime.getRuntime().exec(new String[] {"sh", "-c", "ps -ef | grep Xvfb | grep -v grep"}); 
0

有很多的這樣做的方法。您可以使用java.lang.ProcessBuilder和「pgrep」來獲取進程ID(PID),如:pgrep -fl java | awk {'print $1'}。或者,如果您在Linux下運行,則可以查詢/proc目錄。

我知道,這看起來很可怕,而且不便攜,甚至執行不力,我同意。但是因爲Java實際上運行在虛擬機中,出於一些荒謬的原因,我在JDK工作超過15年後無法弄清楚,這就是爲什麼看不到JVM空間之外的東西,如果你覺得這很荒謬考慮一下。你可以做一切,甚至分叉和加入子進程(這些是多任務的可怕的方式,當世界不知道線程並行線程,什麼地獄是怎麼回事了Java?! )。

這將給我一個巨大的討論,我知道,但無論如何,有一個非常好的API,我已經在我的項目中使用,它足夠穩定(它是OSS,所以你仍然需要在真正相信API):https://github.com/jezhumble/javasysmon

JavaDoc:http://jezhumble.github.io/javasysmon/,搜索類com.jezhumble.javasysmon.OsProcess,她會做的伎倆。祝你好運,祝你好運。

相關問題