Filtering top command output
Solution 1:
top -pid 3907 -stats "pid,command,cpu"
-
-pid 3907
: your process ID -
-stats pid,command,cpu
: only show process ID, name and CPU%
No need to run awk
on the output.
If you want to post-process the output, use -l 0
to run in logging mode (0 means indefinitely, everything else limits number of samples). Output will look like this (two repetitions):
Processes: 72 total, 3 running, 1 stuck, 68 sleeping, 326 threads
2011/05/10 19:15:13
Load Avg: 0.14, 0.14, 0.09
CPU usage: 20.0% user, 26.66% sys, 53.33% idle
SharedLibs: 5304K resident, 5208K data, 0B linkedit.
MemRegions: 16345 total, 1048M resident, 54M private, 338M shared.
PhysMem: 726M wired, 1802M active, 687M inactive, 3215M used, 750M free.
VM: 169G vsize, 1036M framework vsize, 5261732(0) pageins, 552476(0) pageouts.
Networks: packets: 46747406/52G in, 32528901/3715M out.
Disks: 9452898/244G read, 11226269/293G written.
PID COMMAND %CPU
3907 WindowServer 0.0
Processes: 72 total, 3 running, 1 stuck, 68 sleeping, 326 threads
2011/05/10 19:15:14
Load Avg: 0.13, 0.14, 0.09
CPU usage: 0.95% user, 1.90% sys, 97.14% idle
SharedLibs: 5304K resident, 5208K data, 0B linkedit.
MemRegions: 16346 total, 906M resident, 54M private, 386M shared.
PhysMem: 726M wired, 1802M active, 687M inactive, 3215M used, 751M free.
VM: 169G vsize, 1036M framework vsize, 5261732(0) pageins, 552476(0) pageouts.
Networks: packets: 46747406/52G in, 32528901/3715M out.
Disks: 9452898/244G read, 11226269/293G written.
PID COMMAND %CPU
3907 WindowServer 2.7
Use awk
or a similar tool to only display every 13th line (as these lines contain the values in that example):
$ top -l 0 -pid 3907 -stats pid,command,cpu | awk 'NR%13==0'
3907 WindowServer 0.0
3907 WindowServer 1.3
3907 WindowServer 2.2
Solution 2:
This certainly can be done and I'm going to explain how I would do it. I'm not pretending this is an optimal approach, but it does the job. I am using Linux (and bash shell), so the default behavior of my top may be slightly different. Thus you may need to tune this mini-howto for your particular scenario.
-
Just run top, without any arguments:
$ top
Here is the header and a relevant line from my output:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2569 user 20 0 339m 86m 10m S 7.8 6.9 6:42.99 java
I have picked up a process that stays in memory for some time and actually consumes CPU, I will be using it as test process for reaching the final goal.
-
By default, top runs in interactive mode. This doesn't suit me, I want to capture the relevant data and print it. I will handle the task of displaying the data interactively after that. Relevant quotes from top manpage:
-b : Batch mode operation Starts top in 'Batch mode', which could be useful for sending output from top to other programs or to a file. In this mode, top will not accept input and runs until the iterations limit you've set with the '-n' command-line option or until killed.
-n : Number of iterations limit as: -n number Specifies the maximum number of iterations, or frames, top should produce before ending.
This is the adjusted top command that prints output only once, then exits:
$ top -b -n 1
-
I know the PID I want to watch, so I'll add one more restriction to top, so it prints data only about that process:
$ top -b -n 1 -p 2569
-
Even in batch mode, top still prints a header, containing misc system-wide stats like uptime, free memory/swap etc. I don't need this. All I need is only one line - the one that contains data about my process, so I'll cut it from the whole output like this:
$ top -b -n 1 -p 2569 | tail -n 2 | head -n 1
As you can see, I've got the second line from 1.
-
I'll pipe this line to awk to extract only the columns I need:
$ top -b -n 1 -p 2569 | tail -n 2 | head -n 1 | awk '{print $1, $12, $9}'
-
Until now, I've been doing these manipulations in command line, now it's the moment to add some persistence and flexibility to our hardcoded particular case. I am moving the whole line into a simple shell script. I'll call it 3top, the name is emphasized because it will be used later:
#!/bin/bash
top -b -n 1 -p 2569 | tail -n 2 | head -n 1 | awk '{print $1, $12, $9}'
-
The PID number is hardcoded, here's how to make the script to accept it as command line argument:
#!/bin/bash
top -b -n 1 -p "$1" | tail -n 2 | head -n 1 | awk '{print $1, $12, $9}'
To make 3top display stats about PID 2569, it must be called like this:
$ ./3top 2569
-
I also want percentage displayed after CPU load, so I'm tuning my 3top script like this:
#!/bin/bash
out=$(top -b -n 1 -p "$1" | tail -n 2 | head -n 1 | awk '{print $1, $12, $9}')
echo "$out%"
I have redirected the whole output of a chain of commands (connected through pipes) into a variable. Then I just print it using echo and add a '%' at the end, since CPU load is the last field
-
At this point I have a batch script that accepts a PID as argument and prints stats once. Want real time monitoring instead? It's easy, because watch can do it! Run the script like this:
$ watch -n 1 3top 2569
It will do real time monitoring by running 3top once per second.
Solution 3:
The top
display format is customizable, but there is not a way to specify display options at the command line. If you are inventive, however, you can probably do what you need by cleverly manipulating the ~/.toprc
file.
Assuming you have not already customized the display of top
(and do not have a ~/.toprc
file):
- Launch
top
. - Press f to enter field select mode.
- For each field that has an
*
next to it that you do not want, press the corresponding letter to deselect that field. For example, press e to deselect theUser Name
field. When you are done, you should only have an*
next toProcess Id
,CPU usage
, andCommand name/line
. - Press Space to return to the main window.
- Press W (i.e. Shift+w) to save the current layout to your
~/.toprc
file. - Quit
top
, then relaunch to verify that your settings are saved. - When you want to return to the default layout, rename
~/.toprc
to something like~/min.toprc
before launchingtop
. When you want to switch to the minimal layout, rename~/min.toprc
back to~/.toprc
before launchingtop
.
This file renaming and launching top
can probably be worked into a simple shell script by someone with an ounce more experience and knowledge than me. You will need special consideration if your regular top
layout has already been customized.