BJPrim BJPrim - 1 year ago 60
Linux Question

Capture %CPU and PID of processes filtered by COMMAND using top command

I need to write a Bash script that does the following:

  1. In the "top" command, I would like to filter the processes by a given COMMAND. In the following I use Google Chrome as an example, which appears as "chrome" in the COMMAND column.

  2. After filtering, there can be zero, one or more processes with COMMAND "chrome" left (this is just to highlight that there is not exactly one process with COMMAND "chrome" in general).

  3. Now I would like to write the current time (hh:mm:ss), the PID of the process and the %CPU value displayed for this process to a file "logfile"

  4. Repeat steps 1 to 3 once every second.

Example: Assuming that there are three "chrome" processes, the output in "logfile" should start like something the following (for the first three seconds):

17:49:12 7954 14.0
17:49:12 7969 9.3
17:49:12 2626 1.3
17:49:13 7954 12.0
17:49:13 7969 6.3
17:49:13 2626 1.2
17:49:14 7954 14.7
17:49:14 7969 8.5
17:49:14 2626 2.1

My ideas so far: Using the command

top -b -n 1 -p 7954 | tail -n 2 | head -n 2 | awk '{print $1, $9}' >> logfile

I filter top by PID (in this case PID == 7954) and the output looks like

7954 6.6

however (since I actually want to filer by COMMAND) I do not know how to filter by COMMAND. In the line above, the "-p 7954" does the filtering for PID==7954, however what do I need to write here to filter by COMMAND==chrome? Also, How can I remove/avoid the header?

According to the time step: I found that the command

date +"%T"

gives me the time in the correct format (hh:mm:ss).

So I just straggle with putting these pieces together and fix the filtering problem mentioned above. Thank you for any help!

Answer Source

Awk can do this; awk '/regex/ { print }' performs the print action only on lines matching regex.

However, you can (and perhaps also should) subsume head and tail as well:

top -b -n 1 | awk 'NR>1 && $10 == "chrome" {print strftime("%T"), $1, $9}' 

... assuming the tenth field of top output contains the command name.