[macos] Limit the output of the TOP command to a specific process name

If you call the top command, you get all the running processes. But how can I limit the output only to a certain process name like "java"?

I've tried this top -l 2 | grep java but in this way you get only snapshots and not a continuously updated list. And top -l 0 | grep java is not really clear.

This question is related to macos unix command-line top-command

The answer is


Suppose .. if we have more than 20 process running on the server with the same name ... this will not help

top -p pgrep oracle | head -n 20 | tr "\\n" "," | sed 's/,$//'

It will try to list and provide real time output of 20 process where we have good chance of missing other prcesses which consumes more resource ....

I am still looking for better option on this


Here's the only solution so far for MacOS:

top -pid `pgrep java | awk 'ORS=" -pid "' | sed 's/.\{6\}$//'`

though this will undesirably report invalid option or syntax: -pid if there are no java processes alive.

EXPLANATION

The other solutions posted here use the format top -p id1,id2,id3, but MacOS' top only supports the unwieldy format top -pid id1 -pid id2 -pid id3.

So firstly, we obtain the list of process ids which have process name "java":

pgrep java

and we pipe this to awk which joins the results with delimitor " -pid "

| awk 'ORS=" -pid "'

Alas, this leaves a trailing delimitor! For example, we may so far have obtained the string "123 -pid 456 -pid 789 -pid ".

We then just use sed to shave off the final 6 characters of the delimitor.

| sed 's/.\{6\}$//'`

We're ready to pass the results to top:

top -pid `...`

Find the pids of the processes you want to monitor and then use the -p option which allows you to provide a list of pids to the top command.

Example:

top -p 18884 -p 18892 -p 18919

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND
18884 user  25   0  672M  95M  9476 S     0.0  1.1   0:02   1 java
18892 user  25   0 2280M 123M 12252 S     0.0  1.5   0:05   1 java
18919 user  22   0 1492M 198M 28708 S     0.0  2.4   0:07   1 java

(I believe you can also pass in a comma-separated list.)


I run it (eg.): top -b | egrep -w 'java|mysqld'


Running the below will give continuous update in console:

bcsmc2rtese001 [~]$ echo $SHELL  
/bin/bash  
bcsmc2rtese001 [~]$ top | grep efare  or watch -d 'top | grep efare' or top -p pid
27728 efare     15   0 75184 3180 1124 S  0.3  0.0 728:28.93 tclsh  
27728 efare     15   0 75184 3180 1124 S  0.7  0.0 728:28.95 tclsh

A more specific case, like I actually was looking for:

For Java processes you can also use jps -q whereby jps is a tool from $JAVA_HOME/bin and hence should be in your $PATH.


how about top -b | grep java


I solved my problem using:

top -n1 -b | grep "proccess name"

in this case: -n is used to set how many times top will what proccess
and -b is used to show all pids

it's prevents errors like : top: pid limit (20) exceeded


I prefer the following so I can still use top interactively without having to look up the pids each time I run it:

top -p `pgrep process-name | tr "\\n" "," | sed 's/,$//'`

Of course if the processes change you'll have to re-run the command.

Explanation:

  • pgrep process-name returns a list of process ids which are separated by newlines
  • tr "\\n" "," translates these newlines into commas, because top wants a comma-separated list of process ids
  • sed is a stream editor, and sed 's/,$//' is used here to remove the trailing comma

Use the watch command

watch -d 'top -n1 | grep mysql'

Using the answer from here I was able to create a one liner

top -pid $(pgrep process_name | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ -pid /g')

This works for me on MacOS 10.12 (Sierra)


The following code updates a list of processes every 5 seconds via the watch command:

watch -n 5 -t top -b -n 1 -p$(pgrep java | head -20 | tr "\\n" "," | sed 's/,$//')


Using the approach mentioned in the answer by Rick Byers:

top -p `pgrep java | paste -sd "," -`

but I had more than 20 processes running so following command can be helpful for someone who encounter a similar situation.

top -p `pgrep java | head -n 20 | paste -sd "," -`

pgrep gets the list of processes with given name - java in this case. head is used to get first 20 pids because top cannot handle more than 20 pids when using -p argument. Finally paste joins the list of pids with ','.

You can control the process name you are looking for in the above command and the number of processes with that name you are interested to watch. You can ignore the head -n 20 part if the number of your processes with the given name is less than 20.


get pid of process:

# pidof <process>

tell top what process pid(s) to display

# top -p <pid1>,<pid2>, etc

example:

landis@linux-e6510:~>pidof konsole
1841 1709
landis@linux-e6510:~>top -p 1841,1709

Top will only display the 2 'konsole' processes. This is useful on a busy server via ssh, not having to pipe thru grep.


Expanding on @dogbane's answer, you can get all the PIDs for a named process with pgrep to do the following:

top -p "$(pgrep -d ',' java)"

I came here looking for the answer to this on OSX. I ended up getting what I wanted with bash and awk:

topfiltered() {
  [[ -z "$1" ]] && return
  dump="/tmp/top_dump"
  rm -f "$dump"
  while :; do
    clear
    [[ -s "$dump" ]] && head -n $(( $LINES - 1 )) "$dump"
    top -l 1 -o cpu -ncols $(( $COLUMNS / 8 )) | awk -v p="$(pgrep -d ' ' $@)" '
        BEGIN { split(p, arr); for (k in arr) pids[arr[k]]=1 }
        NR<=12 || ($1 in pids)
    ' >"$dump"
  done
}

I loop top in logging mode and filter it with awk, building an associative array from the output of pgrep. Awk prints the first 12 lines, where line 12 is the column headers, and then every line which has a pid that's a key in the array. The dump file is used for a more watchable loop.


just top -bn 1 | grep java will do the trick for you


Examples related to macos

Problems with installation of Google App Engine SDK for php in OS X dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac Could not install packages due to an EnvironmentError: [Errno 13] How do I install Java on Mac OSX allowing version switching? Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) Can't compile C program on a Mac after upgrade to Mojave You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory. (mac user) How can I install a previous version of Python 3 in macOS using homebrew? Could not install packages due to a "Environment error :[error 13]: permission denied : 'usr/local/bin/f2py'"

Examples related to unix

Docker CE on RHEL - Requires: container-selinux >= 2.9 What does `set -x` do? How to find files modified in last x minutes (find -mmin does not work as expected) sudo: npm: command not found How to sort a file in-place How to read a .properties file which contains keys that have a period character using Shell script gpg decryption fails with no secret key error Loop through a comma-separated shell variable Best way to find os name and version in Unix/Linux platform Resource u'tokenizers/punkt/english.pickle' not found

Examples related to command-line

Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) Flutter command not found Angular - ng: command not found how to run python files in windows command prompt? How to run .NET Core console app from the command line Copy Paste in Bash on Ubuntu on Windows How to find which version of TensorFlow is installed in my system? How to install JQ on Mac by command-line? Python not working in the command line of git bash Run function in script from command line (Node JS)

Examples related to top-command

top -c command in linux to filter processes listed based on processname Limit the output of the TOP command to a specific process name Network usage top/htop on Linux