在java中用top命令查找进程信息

Find the process information with top command in java

我想使用top命令获取进程信息。我有下面的代码,但它不起作用,它只是存在没有任何输出的程序。我的目标是获取进程名称、进程 ID 和内存使用情况,但那是后面的部分。目前,我一直在使用 grep.

使用 Java 中的 top 命令获取进程信息
public void getProcessInfo(String processName) {
    Runtime rt = Runtime.getRuntime();
    try {
        String[] cmd = { "/bin/sh", "-c", "top | grep " + processName };
        Process proc = rt.exec(cmd);
        InputStream stdin = proc.getInputStream();
        InputStreamReader isr = new InputStreamReader(stdin);
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);       
        }
    } catch (Exception e) {
        e.printStackTrace(e);
    }
}

这个问题之前已经被问过和回答过很多次了:

在正常模式下,top 命令 不会 输出到 stdout,这就是为什么您不能简单地将其输出通过管道传输到另一个 CLI 实用程序的原因试着做。相反,您必须使用 -b 标志将命令切换为 "batch mode"。此外,如果要处理结果,则必须将迭代次数限制为单次(在非交互模式下进一步迭代没有意义):

top -b -n 1 | grep "whatever"

这在命令手册页中有记录:man top

祝您项目愉快!

Runtime.exec 已过时。请改用 ProcessBuilder

您可以完全避免使用 grep 或任何管道,从而使您的任务变得相当容易。当你有 Java 时谁还需要 grep?

根据 arkascha 的回答,您可以这样做:

String processLine = null;

ProcessBuilder builder = new ProcessBuilder("top", "-b", "-n", "1");
Process proc = builder.start();

try (BufferedReader stdin = new BufferedReader(
    new InputStreamReader(proc.getInputStream()))) {

    String line;
    while ((line = stdin.readLine()) != null) {
        if (line.contains(processName)) {   // No need for grep
            processLine = line;
            break;
        }
    }
}

您可能想跳过摘要信息和 header 行:

String processLine = null;

ProcessBuilder builder = new ProcessBuilder("top", "-b", "-n", "1");
Process proc = builder.start();

try (BufferedReader stdin = new BufferedReader(
    new InputStreamReader(proc.getInputStream()))) {

    String line;

    // Blank line indicates end of summary.
    while ((line = stdin.readLine()) != null) {
        if (line.isEmpty()) {
            break;
        }
    }

    // Skip header line.
    if (line != null) {
        line = stdin.readLine();
    }

    if (line != null) {
        while ((line = stdin.readLine()) != null) {
            if (line.contains(processName)) {   // No need for grep
                processLine = line;
                break;
            }
        }
    }
}