Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I would like to get a list of all the processes that descend (e.g. children, grand-children, etc) from $pid. This is the simplest way I've come up with:

pstree -p $pid | tr "\n" " " |sed "s/[^0-9]/ /g" |sed "s/\s\s*/ /g"

Is there any command, or any simpler way to get the full list of all descendant processes?

Thanks!

share|improve this question
    
Is there a reason you need them all on one line? What are you doing with that output? I have a feeling that this is an xy problem, and you are asking the wrong question. –  jordanm Mar 12 '13 at 17:03
    
I don't care about the format as long as it's clean (i.e. I don't care about '\n' delimited vs. ' ' delimited). Practical use case is: a) a daemonizer script I wrote out of pure masochism (specifically, the "stop" functionality has to deal with whatever tree of processes the daemonized process spawned); and b) a timeout script that will kill whatever the timed-out process managed to create. –  STenyaK Mar 12 '13 at 21:06
1  
@STenyaK Your use cases make me think you're looking for process groups and a negative argument to kill. See unix.stackexchange.com/questions/9480/…, unix.stackexchange.com/questions/50555/… –  Gilles Mar 12 '13 at 21:51
    
@Gilles using ps ax -opid,ppid,pgrp,cmd I see there are many processes that share the same pgrp as the exact subtree I want to kill. (Additionally, I can't see the setpgrp program listed anywhere in debian stable packages: packages.debian.org/… ) –  STenyaK Mar 13 '13 at 7:42
1  
Another use case: renice/ionice on a whole process tree that's eating too many resources, e.g. a large parallel build. –  Cheetah Sep 25 '13 at 4:02

3 Answers 3

up vote 6 down vote accepted

The following is somewhat simpler, and has the added advantage of ignoring numbers in the command names:

pstree -p $pid | grep -o '([0-9]\+)' | grep -o '[0-9]\+'

Or with Perl:

pstree -p $pid | perl -ne 'print "$1\n" while /\((\d+)\)/g'

We're looking for numbers within parentheses so that we don't, for example, give 2 as a child process when we run across gif2png(3012). But if the command name contains a parenthesized number, all bets are off. There's only so far text processing can take you.

So I also think that process groups are the way to go. If you'd like to have a process run in its own process group, you can use the 'pgrphack' tool from the Debian package 'daemontools':

pgrphack my_command args

Or you could again turn to Perl:

perl -e 'setpgid or die; exec { $ARGV[0] } @ARGV;' my_command args

The only caveat here is that process groups do not nest, so if some process is creating its own process groups, its subprocesses will no longer be in the group that you created.

share|improve this answer
    
Child processes are arbitrary and may or may not use process groups themselves (I cannot assume anything). However your answer comes the closest to what seesm to be achievable in Linux, so I'll accept it. Thanks. –  STenyaK Jul 17 '13 at 11:57

In each of your two (seemingly very artificial) use cases, why do you want to kill some unfortunate process's sub-processes? How do you know better than a process when its children should live or die? This seems like poor design to me; a process should clean up after itself.

If you really do know better, then you should be forking these sub-processes, and the 'daemonized process' is apparently too dumb to be trusted to fork(2).

You should avoid keeping lists of child processes or grovelling through the process tree, eg by putting the child processes in a separate process group as suggested by @Gilles.

In any case, I suspect that your daemonized process would be better off creating a worker thread pool (which necessarily dies along with its containing process) than a deep tree of sub-sub-sub-processes, which something somewhere then has to clean up.

share|improve this answer
    
Both use cases are used in a continuous integration/testing environment, so they have to deal with the possibility of a bug existing in the child process/es. This bug may manifest itself as inability to properly shutdown themselves or their children, so I need a way to ensure that I can close them all in the worst case. –  STenyaK Jul 17 '13 at 11:55
1  
In that case, I'm with @Gilles and @Jander; process groups are the best way. –  user2034574 Sep 13 '13 at 13:58

The shortest version I have found that also deals correctly with commands like pop3d:

pstree -p $pid | perl -ne 's/\((\d+)\)/print " $1"/ge'

It deals wrongly if you have commands that have weird names like: my(23)prog.

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.