简体   繁体   English

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

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

I googled and checked the SO if there is any code to find PID of any other process.如果有任何代码可以找到任何其他进程的 PID,我用谷歌搜索并检查了 SO。 There is a solution to create a shell script with the command "ps -eaf | grep myprocess" in it and executing that script from java.有一种解决方案可以在其中使用命令“ps -eaf | grep myprocess”创建 shell 脚本并从 java 执行该脚本。

But I want to execute using java ProcessBuilder or Runtime methods.但我想使用 java ProcessBuilder 或 Runtime 方法执行。 Below is the code that I have tried which is not giving me null as output.下面是我尝试过的代码,它没有给我 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();
    }
}

The output for the command is:该命令的 output 是:

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

Please let me know if there is any error in my code as when I search manually from shell i do get the expected output as below:请让我知道我的代码中是否有任何错误,因为当我从 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

[UPDATED CODE - Without the grep command] [更新代码 - 没有 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();
    }
}

I have added the code that is working, when I am passing command as:当我将命令传递为:

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

Thanks in advance for any leads.提前感谢任何线索。

As @Slimo answer indicates you must launch a shell to execute a shell command (the pipe), and read the error stream to determine what may have gone wrong.正如@Slimo 的答案所示,您必须启动 shell 来执行 shell 命令(管道),并阅读错误 stream 以确定可能出了什么问题。

Launching subprocess without using waitFor() or consuming stdout and stderr at SAME time can lead to issues, use file redirect or as in this example merge stderr -> stdout and read one stream only:启动子进程而不使用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));
    

In later JDK you don't need ProcessBuilder, you may find all the process attributes in the data-structures returned by ProcessHandle :在以后的 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()))

Your problem is that you are trying to use the pipe in your command, so you need a shell to execute it.您的问题是您尝试在命令中使用 pipe,因此您需要 shell 来执行它。 You can use the following command:您可以使用以下命令:

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

You can read more here: Using Java ProcessBuilder to Execute a Piped Command您可以在此处阅读更多信息: 使用 Java ProcessBuilder 执行管道命令

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

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