arpit joshi
arpit joshi

Reputation: 2134

Find the process information with top command in java

I want to get the process information using the top command. I have the below code but it is not working, it just exists the program without any output. My goal is to get the process name, process ID, and memory usage, but that's the later part. For now, I am stuck in getting process information using the top command in Java using grep.

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

Upvotes: 1

Views: 3261

Answers (2)

VGR
VGR

Reputation: 44355

Runtime.exec is obsolete. Use ProcessBuilder instead.

You can make your task considerably easier by avoiding the use of grep, or any piping, altogether. Who needs grep when you have Java?

Building on arkascha's answer, you could do:

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

You probably want to skip the summary information and header line:

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

Upvotes: 1

arkascha
arkascha

Reputation: 42925

This question has been asked and answered many times before:

In normal mode the top command does not output to stdout, which is why you cannot simply pipe its output into another CLI utility as you try to do. Instead you have to switch the command to "batch mode" by using the -b flag. In addition you have to limit the number of iterations to a single if you want to process the result (no sense for further iterations in non interactive mode):

top -b -n 1 | grep "whatever"

This is documented on the commands man page: man top

Have fun with your project!

Upvotes: 2

Related Questions