如果有任何代碼可以找到任何其他行程的 PID,我搜索并檢查了 SO。有一個解決方案可以使用命令“ps -eaf | grep myprocess”創建一個shell腳本并從java執行該腳本。
但我想使用 java ProcessBuilder 或 Runtime 方法執行。下面是我嘗試過的代碼,它沒有給我 null 作為輸出。
import java.io.*;
public class TestShellCommand {
public static void main(String args[]) {
Process p = null;
String command = "ps -ef | grep myProcess";
try {
// p = new ProcessBuilder(command).start();
p = Runtime.getRuntime().exec(command);
BufferedReader br[] = new BufferedReader[2];
br[1] = new BufferedReader(new InputStreamReader(p.getErrorStream()));
br[0] = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
if(br[0].readLine() == null){
System.out.println("The input stream is null.");
}
while ((line = br[0].readLine()) != null) {
System.out.println(line);
}
try {
br[0].close();
} catch (Exception a) {
a.printStackTrace();
}
try {
br[1].close();
} catch (Exception a) {
a.printStackTrace();
}
} catch (Exception grrr) {
grrr.printStackTrace();
} finally {
try {
closeStreams(p);
p.destroy();
} catch (Exception r) {
r.printStackTrace();
}
}
}
static void closeStreams(Process p) throws IOException {
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
}
}
命令的輸出是:
java TestShellCommand
The input stream is null.
{sdc@ip-172-31-32-49}[26] echo $?
0
請讓我知道我的代碼中是否有任何錯誤,因為當我從 shell 手動搜索時,我確實得到了預期的輸出,如下所示:
ps -ef | grep myProcess
root 7433 1 0 10:33 ? 00:00:00 myProcess hello
sdc 19894 14130 0 11:24 pts/7 00:00:00 grep myProcess
[更新代碼 - 沒有 grep 命令]
import java.io.*;
public class TestShellCommand {
public static void main(String args[]) {
Process p = null;
String [] command = {"ps", "-eaf"};
try {
p = Runtime.getRuntime().exec(command);
BufferedReader br[] = new BufferedReader[2];
br[1] = new BufferedReader(new InputStreamReader(p.getErrorStream()));
br[0] = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
if(br[0].readLine() == null){
System.out.println("The input stream is null.");
}
while ((line = br[0].readLine()) != null) {
System.out.println(line);
}
// Then code to find by process name by using string methods ...
try {
br[0].close();
} catch (Exception a) {
a.printStackTrace();
}
try {
br[1].close();
} catch (Exception a) {
a.printStackTrace();
}
} catch (Exception grrr) {
grrr.printStackTrace();
} finally {
try {
closeStreams(p);
p.destroy();
} catch (Exception r) {
r.printStackTrace();
}
}
}
static void closeStreams(Process p) throws IOException {
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
}
}
當我將命令傳遞為:
new String[]{"/bin/sh","-c", "ps -eaf | grep " "myProcess" " | grep -v grep"}- 空回應。new String[] {"ps", "-eaf", "grep -m 1 myProcess", "awk -F ' ' '{print $2}' "}- 空回應。
提前感謝您的任何線索。
uj5u.com熱心網友回復:
正如@Slimo 的回答所指出的,您必須啟動一個 shell 來執行一個 shell 命令(管道),并讀取錯誤流以確定可能出錯的地方。
waitFor()在同一時間啟動子行程而不使用或消耗 stdout 和 stderr 可能會導致問題,使用檔案重定向或在本例中合并 stderr -> stdout 并僅讀取一個流:
String procname = "myProcess";
String[] cmd = new String[]{"bash","-c", "ps -eaf | grep " procname " | grep -v grep"}
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process process = pb.start();
process.getInputStream().transferTo(System.out);
int rc = process.waitFor();
if (rc != 0)
throw new RuntimeException("Failed rc=" rc " cmd=" Arrays.toString(cmd));
在以后的 JDK 中,您不需要 ProcessBuilder,您可能會在回傳的資料結構中找到所有流程屬性ProcessHandle:
ProcessHandle.allProcesses()
.filter(ph -> ph.info().command().isPresent() && ph.info().command().get().contains(procname))
.forEach(ph -> System.out.println("PID: " ph.pid() " command: " ph.info().command()))
uj5u.com熱心網友回復:
您的問題是您試圖在命令中使用管道,因此您需要一個 shell 來執行它。您可以使用以下命令:
p = new ProcessBuilder("/bin/sh", "-c", "ps -aux | grep myProcess").start();
您可以在此處閱讀更多資訊:使用 Java ProcessBuilder 執行管道命令
為了測驗它,我top在 shell 中啟動并使用它作為 grep 模式運行命令。這是我得到的輸出:
<edited> 139890 0.4 0.0 23640 4376 pts/0 S 16:05 0:00 top
<edited> 139945 0.0 0.0 20996 3448 ? S 16:06 0:00 /bin/bash -c ps -aux | grep top
<edited> 139947 0.0 0.0 20536 2776 ? S 16:06 0:00 grep top
根據您的評論,我建議您首先在 shell 中運行命令以查看輸出并檢查它是否與 Java 程式中的輸出匹配。我想myProcess這只是要檢查的實際程序的占位符。
我注意到的一件事是,當從 snap 運行 htop 時,并在 htop 之后使用上面的代碼 grep 將回傳您評論中的答案,但按 top 進行 grepping 將包括實際程序。我還檢查了 gedit,它看起來像 grep 和 gedit 一樣回傳,但僅使用edit將回傳實際程序。不確定在這種情況下有什么問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/391138.html
