3

I need to show all processes under a certain program. If I do top -p PID I will only get one program.

I want to type top -p 381 extra_args to get

  PID USER      PR  NI    VIRT    RES  %CPU  %MEM     TIME+ S COMMAND                                                                            
  381 root      20   0 8715.7m  12.5m   0.0   0.3   0:48.42 S  `- /usr/bin/program          
10034 root      20   0 8476.3m   2.3m   0.0   0.1   0:00.03 S      `- -/usr/bin/sh                                                            
10036 root      20   0 8488.3m   2.2m   0.0   0.1   0:00.01 S          `- /usr/bin/sh ./login.sh                                              
10037 root      20   0    3.9m   3.1m   0.0   0.1   0:00.54 S              `- /usr/bin/bash --login +h                                           
19995 root      20   0 8506.3m   2.4m   0.0   0.1   0:00.01 S      `- -/usr/bin/sh                                                            
19997 root      20   0 8512.3m   2.2m   0.0   0.1   0:00.01 S          `- /usr/bin/sh ./login.sh                                              
19998 root      20   0    3.9m   3.1m   0.0   0.1   0:00.89 S              `- /usr/bin/bash --login +h                                           
30644 root      20   0    2.8m   2.1m   0.0   0.1   0:00.03 S                  `- make -j8                                                       
30647 root      20   0    2.8m   2.0m   0.0   0.1   0:00.01 S                      `- make all-recursive                                         
30648 root      20   0    2.2m   1.4m   0.0   0.0   0:00.00 S                          `- /bin/sh -c fail=; \ if (target_option=k; case ${targe+ 
30661 root      20   0    2.8m   2.1m   0.0   0.1   0:00.06 S                              `- make all-am                                        
30671 root      20   0    2.4m   1.6m   0.0   0.0   0:00.04 S                                  `- /bin/sh ./libtool --silent --tag=CC --mode=co+ 
30808 root      20   0    3.9m   0.3m   0.0   0.0   0:00.00 S                                      `- gcc -DHAVE_CONFIG_H -I. -I.. -I./include + 
30816 root      20   0  132.3m 117.7m  98.7   3.1   0:43.18 R                                          `- /usr/libexec/gcc/aarch64-unknown-linu+ 
30675 root      20   0    2.4m   1.6m   0.0   0.0   0:00.04 S                                  `- /bin/sh ./libtool --silent --tag=CC --mode=co+ 
31230 root      20   0    3.9m   0.3m   0.0   0.0   0:00.00 S                                      `- gcc -DHAVE_CONFIG_H -I. -I.. -I./include + 
31231 root      20   0   88.3m  76.6m  99.4   2.0   0:20.08 R                                          `- /usr/libexec/gcc/aarch64-unknown-linu+ 
31074 root      20   0    2.4m   1.6m   0.0   0.0   0:00.05 S                                  `- /bin/sh ./libtool --silent --tag=CC --mode=co+ 
31274 root      20   0    3.9m   0.3m   0.0   0.0   0:00.00 S                                      `- gcc -DHAVE_CONFIG_H -I. -I.. -I./include  

Instead of top -p 381 which gives

  PID USER      PR  NI    VIRT    RES  %CPU  %MEM     TIME+ S COMMAND                                                                            
  381 root      20   0 8715.7m  12.5m   0.0   0.3   0:48.42 S  `- /usr/bin/program  

Here is my top usage

top -hv | -bcEeHiOSs1 -d secs -n max -u|U user -p pid(s) -o field -w [cols]

3 Answers3

3

top is probably not the right tool for a job.

ps kinda works but you need to know all the pids in the tree which defeats the whole purpose.

ps u -p 2307,2312,2334,9379 --ppid 2307,2312,2334,9379 --forest
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      2307  0.0  0.0   2200   264 ?        Ss   Dec15   0:00 runsv eto-netnses
eto       2312  0.0  0.0   2748   420 ?        S    Dec15   0:00  \_ s6-svscan netnses
eto       2334  0.0  0.0   2756   416 ?        S    Dec15   0:00      \_ s6-supervise netns-nsholder-vpn-tunnel
eto       9379  0.0  0.0   2184   300 ?        Ss   Dec17   0:00          \_ netns-nsholder-daemon

Easiest way is to use pstree, which can draw a tree for you but lacks ability to output other information:

: pstree -p 2307 -a -u                                           
runsv,2307 eto-netnses
  └─s6-svscan,2312,eto netnses
      └─s6-supervise,2334 netns-nsholder-vpn-tunnel
          └─pause,9379

If you can get session id of the process tree and all processes in that tree of interest are running in that same session you can use that SID as selector for ps --forest format, but in my case this breaks, because ps won't cross session boundaries in this mode, which is what is happening here (pause a.k.a netns-nsholder-daemon from above listing is missing here, due to it running in new SID):

: ps -p 2307 -o pid,sess
  PID  SESS
 2307  2307
: ps u -s 2307 --forest 
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      2307  0.0  0.0   2200   264 ?        Ss   Dec15   0:00 runsv eto-netnses
eto       2312  0.0  0.0   2748   420 ?        S    Dec15   0:00  \_ s6-svscan netnses
eto       2334  0.0  0.0   2756   416 ?        S    Dec15   0:00      \_ s6-supervise netns-nsholder-vpn-tunnel

At this point I believe you are probably better off with htop.

etosan
  • 1,054
  • thanks for your suggestion then I guess we can use top. ps will need to be re run I needed a filter for top – Bret Joseph Dec 19 '21 at 06:10
  • As far as I know it's impossible to achieve what you want with top. If you want dynamic refresh, then htop really is your answer. Install htop if you dont have it already,and start it. If you are not in "tree mode" already press F5 to switch to it - now you see the whole tree population on the machine as giant tree. Find your process of interest and pres F to follow it as the leader. Under the leader the tree will now update as processes come and go. – etosan Dec 19 '21 at 06:42
  • alright, thanks – Bret Joseph Dec 19 '21 at 07:01
1

There's is no simple or direct way. If you really want the top refreshing feature for a pid and any of the sub-pids you can use something like pgrep on the command line.

If the PID you are interested in is 1234 then this command would work:

top -p 1234 -p `pgrep -P 1234 -d,`

The pgrep finds all processes that have the parent process 1234 and use the delimiter of a comma.

There are a few limitations to this:

  • It doesn't "re-scan" so if there are new child processes then they don't show
  • It won't find an entire tree, just child processes of the requested one, so children of the children won't show up
  • Any existing top filters are in play which may or may not be what you want. I don't show idle processes (the i command in top) so initially top showed nothing. Pressing i showed them up.
0

Another way to monitor a process tree

Let's say we have a process called myProcess with the ID 1234

watch -d -n 1 "pstree -a 1234"

or

watch -d -n 1 "pstree -a `pgrep -f myProcess`"

This will show you the process tree in a new window, updating it every second and highlighting the changes between each update.

watch will run until interrupted. (ctrl-c)

Synopsis

pgrep -f <command> returns just the process ID for a command

pstree shows the process tree.

  • -a shows command line arguments
  • (You may vary the pstree arguments to your needs, please refer to the pstree man page.)

watch runs command repeatedly, displaying its output

  • -n <n> run every n seconds
  • -d highlight the differences between successive updates