繁体   English   中英

如何在 java 中执行命令“ps -eaf | grep myprocess”

[英]how to execute command "ps -eaf | grep myprocess" in java

如果有任何代码可以找到任何其他进程的 PID,我用谷歌搜索并检查了 SO。 有一种解决方案可以在其中使用命令“ps -eaf | grep myprocess”创建 shell 脚本并从 java 执行该脚本。

但我想使用 java ProcessBuilder 或 Runtime 方法执行。 下面是我尝试过的代码,它没有给我 null 作为 output。

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();
    }
}

该命令的 output 是:

java TestShellCommand
The input stream is null.
{sdc@ip-172-31-32-49}[26] echo $?
0

请让我知道我的代码中是否有任何错误,因为当我从 shell 手动搜索时,我确实得到了预期的 output,如下所示:

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();
    }
}

当我将命令传递为:

  1. new String[]{"/bin/sh","-c", "ps -eaf | grep "+ "myProcess" +" | grep -v grep"} - 空响应。
  2. new String[] {"ps", "-eaf", "grep -m 1 myProcess", "awk -F ' ' '{print $2}' "} - 空响应。

提前感谢任何线索。

正如@Slimo 的答案所示,您必须启动 shell 来执行 shell 命令(管道),并阅读错误 stream 以确定可能出了什么问题。

启动子进程而不使用waitFor()或同时使用 stdout 和 stderr 可能会导致问题,使用文件重定向或在本例中合并 stderr -> stdout 并仅读取一个 stream :

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()))

您的问题是您尝试在命令中使用 pipe,因此您需要 shell 来执行它。 您可以使用以下命令:

p = new ProcessBuilder("/bin/sh", "-c", "ps -aux | grep myProcess").start();

您可以在此处阅读更多信息: 使用 Java ProcessBuilder 执行管道命令

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM