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.
Related videos on Youtube
smokinguns
Updated on September 18, 2022Comments
-
smokinguns over 1 year
I'm running a Mac and want to filter the output of the
top
command for a particular process such that only the PID, COMMAND and %CPU columns are displayed.After getting the PID of the process, I run:
top -pid 1234
However this displays more than 15 columns for that process. Can I pipe the output of 'the command in to awk and display only the:
PID COMMAND %CPU
columns?
I don't want to store the output in a text file and then process it. I'm interested in monitoring the process in real time.
-
HikeMike almost 13 yearsThe user is on OS X and has no Gnu
top
. invalid option or syntax: -b. No idea why this was repeatedly upvoted. -
HikeMike almost 13 yearsGnu
top
(inprocps
) cannot be installed using Homebrew, MacPorts or Fink and cannot be compiled from source using eithermake
orcc top.c
. -
DrBeco about 7 yearsIs it possible to add a filter (even if manually) to
.toprc
? I like to add the filterRUID>999
at startup. -
AstraSerg over 4 years
# top -p1 -stats "pid,command,cpu" top: unknown option 't'
-
HikeMike over 4 years@AstraSerg Works for me. Note that this is a Mac OS question, which has a different
top
than Linux.