Easily find all the child processes of a process?

Hi folks, This is likely an easy one, but my brain is fading rapidly at the moment.. Is there a way to easily collect all child (and grandchild, etc) processes of a particular process? I know I can do ps --ppid $PID to get the immediate children, and I can use pstree -p $PID to see all the descendants in graphical form, but I want to get an easy to parse list. Any ideas, or is this a case of writing it myself? cheers! Chris -- Chris Samuel : http://www.csamuel.org/ : Melbourne, VIC

On Thu, Jun 27, 2013 at 04:34:33PM +1000, Chris Samuel wrote:
Is there a way to easily collect all child (and grandchild, etc) processes of a particular process?
I know I can do ps --ppid $PID to get the immediate children, and I can use pstree -p $PID to see all the descendants in graphical form, but I want to get an easy to parse list.
the simplest way I can think of is to use pstree's '-A' option to get ASCII rather than VT100 line-drawing characters and then pipe the output into sed to transform non-numeric characters into spaces. optionally pipe into xargs to get all the PIDs on one line and get rid of any extra spaces. e.g. $ pstree -A -p 13648 | sed -e 's/[^0-9]\+/ /g' | xargs 13648 14378 14379 14380 14381 14382 14383 14384 14385 14386 14387 31743 31744 31749 14388 14389 14390 14391 14392 14393 14394 14395 14396 14397 14398 14399 14400 14401 16089 22087 605 606 607 you now have a list of PIDs - you can use 'ps -p' or lsof or whatever to get whatever further information you need about them. BTW, PID 13648 on my system at the moment is a bash shell with lots of sub-processes (mostly several backgrounded mutt processes, including the mutt and vim processes I am writing this reply with) WARNING: this simple sed script will work in most cases but is overly simplistic - if the process name contains any digits, they will be printed too (e.g. for "gdm3", "3" would be printed). a better solution would extract only the pid numbers within the parentheses from pstree's output. hmmm...something as simple as deleting any digits immediately preceded by a non-digit-or-open-parenthesis would probably do the trick. something like: sed -e 's/[^()0-9][0-9]\+//' $ pstree -A -p 13648 | sed -e 's/[^(0-9][0-9]\+//' -e 's/[^0-9]\+/ /g' | xargs However, IFF you are certain that the process names of all child processes contain no digits, then it's safe to use the simple version. craig -- craig sanders <cas@taz.net.au> BOFH excuse #2: solar flares

On Thu, Jun 27, 2013 at 06:18:55PM +1000, Craig Sanders wrote:
On Thu, Jun 27, 2013 at 04:34:33PM +1000, Chris Samuel wrote:
Is there a way to easily collect all child (and grandchild, etc) processes of a particular process?
the simplest way I can think of is to use pstree's '-A' option to get
probably a good idea to use pstree's '-l' option for long output (otherwise output width will be truncated to $COLUMNS or 132 chars max). $ pstree -l -A -p 13648 | sed -e 's/[^(0-9][0-9]\+//' -e 's/[^0-9]\+/ /g' | xargs craig -- craig sanders <cas@taz.net.au> BOFH excuse #64: CPU needs recalibration

Chris Samuel <chris@csamuel.org> writes:
Hi folks,
This is likely an easy one, but my brain is fading rapidly at the moment..
Is there a way to easily collect all child (and grandchild, etc) processes of a particular process?
I know I can do ps --ppid $PID to get the immediate children, and I can use pstree -p $PID to see all the descendants in graphical form, but I want to get an easy to parse list.
Any ideas, or is this a case of writing it myself?
HTFU and write it. It's just simple recursion. $ f(){ for i; do x=$(pgrep -P $i)&& { echo $x;f $x; } ;done; } Testing: $ ps fux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND twb 25223 0.0 0.1 4572 1072 tty1 S+ Jun16 0:09 screen -DRR twb 20322 2.8 5.8 47476 43724 ? Ss Jun18 395:58 emacs --daemon twb 1056 0.4 1.6 15988 12548 ? Ss Jun10 126:37 SCREEN -DRR twb 1057 0.0 0.0 3372 464 ? S Jun10 0:00 \_ tail -f /home/twb/.emacs.d/irc-activity twb 20318 0.0 0.0 1588 600 pts/0 Ss+ Jun18 0:00 \_ emacsclient --tty -c twb 5927 1.3 2.1 20044 16236 pts/3 Ss+ 10:33 0:40 \_ emacs -f gnus twb 6444 0.5 0.3 5976 2936 pts/1 Ss 11:18 0:01 \_ bash twb 6532 0.0 0.1 4192 872 pts/1 R+ 11:21 0:00 | \_ ps fux twb 6514 7.0 0.3 5976 2928 pts/2 Ss 11:21 0:00 \_ bash twb 6531 0.5 0.0 3344 432 pts/2 S+ 11:21 0:00 \_ sleep 1h twb 1051 0.0 0.0 2664 720 ? Ss Jun10 0:01 //bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session twb 1050 0.0 0.0 4592 588 ? Ss Jun10 2:32 gpg-agent --daemon twb 1042 0.0 0.0 2628 524 ? Ss Jun10 1:46 ssh-agent -t12h $ f 1056 1057 5927 6444 6514 20318 6531 $

On 28/06/13 11:23, Trent W. Buck wrote:
HTFU and write it. It's just simple recursion.
Actually thanks to Craig no recursion is necessary, I had to modify my version as Craigs seemed to have issues with processes that were numbers, but what I ended up with was: pstree -l -A -p $(pidof pbs_mom) | sed -e 's/(/\n/g' | sed -e 's/).*//' | egrep '^[1-9]+' | fgrep -v $(pidof pbs_mom) So that will find you all the children (processes and threads) of pbs_mom excluding pbs_mom itself. Thanks all! Chris -- Chris Samuel : http://www.csamuel.org/ : Melbourne, VIC

On Fri, Jun 28, 2013 at 12:59:50PM +1000, Chris Samuel wrote:
Actually thanks to Craig no recursion is necessary, I had to modify my version as Craigs seemed to have issues with processes that were numbers, but what I ended up with was:
pstree -l -A -p $(pidof pbs_mom) | sed -e 's/(/\n/g' | sed -e 's/).*//' | egrep '^[1-9]+' | fgrep -v $(pidof pbs_mom)
So that will find you all the children (processes and threads) of pbs_mom excluding pbs_mom itself.
this may be good enough for many cases, but it'll be wrong in the case of processes that are rapidly forking. I'm not sure what your exact use case is, but in general cgroups are the best way to keep track of processes. once the moment-in-time info is snapshotted for userspace (eg. pstree) to use it's already out of date, wheras things like cgroup freeze/thaw and kills are definitive if used properly. ie. no rogue processes are possible. cheers, robin

On Sun, 30 Jun 2013 10:27:48 AM Robin Humble wrote:
I'm not sure what your exact use case is, but in general cgroups are the best way to keep track of processes.
This is to catch an obscure bug in Torque 2.4.x where occasionally, if the kernel has gotten itself into an odd state, jobs can start up outside of the cpuset they are meant to be in due to a cpuset creation failure. :-( I'd prefer pbs_mom to fail job start up if it can't create the cpuset but beggars can't be choosers, and we'll be moving to Slurm soon anyway. cheers! Chris -- Chris Samuel : http://www.csamuel.org/ : Melbourne, VIC This email may come with a PGP signature as a file. Do not panic. For more info see: http://en.wikipedia.org/wiki/OpenPGP

Trent W. Buck wrote:
Chris Samuel <chris@csamuel.org> writes:
Hi folks,
This is likely an easy one, but my brain is fading rapidly at the moment..
Is there a way to easily collect all child (and grandchild, etc) processes of a particular process?
I know I can do ps --ppid $PID to get the immediate children, and I can use pstree -p $PID to see all the descendants in graphical form, but I want to get an easy to parse list.
Any ideas, or is this a case of writing it myself? HTFU and write it. It's just simple recursion.
$ f(){ for i; do x=$(pgrep -P $i)&& { echo $x;f $x; } ;done; }
Testing:
$ ps fux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND twb 25223 0.0 0.1 4572 1072 tty1 S+ Jun16 0:09 screen -DRR twb 20322 2.8 5.8 47476 43724 ? Ss Jun18 395:58 emacs --daemon twb 1056 0.4 1.6 15988 12548 ? Ss Jun10 126:37 SCREEN -DRR twb 1057 0.0 0.0 3372 464 ? S Jun10 0:00 \_ tail -f /home/twb/.emacs.d/irc-activity twb 20318 0.0 0.0 1588 600 pts/0 Ss+ Jun18 0:00 \_ emacsclient --tty -c twb 5927 1.3 2.1 20044 16236 pts/3 Ss+ 10:33 0:40 \_ emacs -f gnus twb 6444 0.5 0.3 5976 2936 pts/1 Ss 11:18 0:01 \_ bash twb 6532 0.0 0.1 4192 872 pts/1 R+ 11:21 0:00 | \_ ps fux twb 6514 7.0 0.3 5976 2928 pts/2 Ss 11:21 0:00 \_ bash twb 6531 0.5 0.0 3344 432 pts/2 S+ 11:21 0:00 \_ sleep 1h twb 1051 0.0 0.0 2664 720 ? Ss Jun10 0:01 //bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session twb 1050 0.0 0.0 4592 588 ? Ss Jun10 2:32 gpg-agent --daemon twb 1042 0.0 0.0 2628 524 ? Ss Jun10 1:46 ssh-agent -t12h
$ f 1056 1057 5927 6444 6514 20318 6531 $
If I understand Trent correctly 1057, 5927,6444, 6514, 20318, 6531 are the 'child process PID's of 1056 ?; as a complete ignoramus in this area (1) does something analogous to the file' pathname' nomenclature, exist for parent-child processes ? (2) can pstree output in this form ? regards Rohan McLeod
_______________________________________________ luv-main mailing list luv-main@luv.asn.au http://lists.luv.asn.au/listinfo/luv-main
participants (5)
-
Chris Samuel
-
Craig Sanders
-
Robin Humble
-
Rohan McLeod
-
trentbuck@gmail.com