Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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.

share|improve this question

3 Answers 3

up vote 5 down vote accepted
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 
share|improve this answer

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.

  1. 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.

  2. 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

  3. 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

  4. 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.

  5. 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}'

  6. 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}'

  7. 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

  8. 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

  9. 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.

share|improve this answer
10  
The user is on OS X and has no Gnu top. invalid option or syntax: -b. No idea why this was repeatedly upvoted. –  Daniel Beck May 10 '11 at 17:20
4  
Gnu top (in procps) cannot be installed using Homebrew, MacPorts or Fink and cannot be compiled from source using either make or cc top.c. –  Daniel Beck May 10 '11 at 18:11

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):

  1. Launch top.
  2. Press f to enter field select mode.
  3. 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 the User Name field. When you are done, you should only have an * next to Process Id, CPU usage, and Command name/line.
  4. Press Space to return to the main window.
  5. Press W (i.e. Shift+w) to save the current layout to your ~/.toprc file.
  6. Quit top, then relaunch to verify that your settings are saved.
  7. When you want to return to the default layout, rename ~/.toprc to something like ~/min.toprc before launching top. When you want to switch to the minimal layout, rename ~/min.toprc back to ~/.toprc before launching top.

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.