List PIDs of child processes

Filed under: Perl tips, Technical — vincent @ 18:31

The next script can be usefull to list all PIDs of a given process and its childs (i.e.: threads also under Linux)

It’s quite brute-force, using /proc extensively. Most probably very Linux specific…

#!/usr/bin/perl -w

use strict;

my $pid=shift @ARGV;

# We'll first make a hash %h where:
# each key is the PID of a process
# each value is a list of the PIDs of the sub-process (direct descendant (ie: children) only, no grand child,...)

# we'll loop on all files under /proc, and take only those whose filename is a number
opendir(DIR,"/proc/") or die ("Can't list proc");
my $file;
my %h=(); # key=pid, value=list of children
while($file=readdir(DIR)) {
        next unless $file =~ m/^d+$/;  # only numbers
        open(STAT,"/proc/$file/stat") or next; # open the stat file for this process
        my $s=<STAT>;
        my @f=split(/s+/,$s);
        # pid: $f[0]   parent PID: $f[3]
        push @{ $h{$f[3]} },$f[0];
        close(STAT);
}
closedir(DIR);

my @pids=();

# recursive function to add a pid and the PIDs of children, grand-children,...
sub add($) {
        push @pids,$_[0];
        map { add($_) } @{ $h{$_[0]} } if (defined($h{$_[0]}));
}
# print join("n", map { $_ . ':' . join(',',sort @{ $h{$_}  } )} sort keys %h);

add($pid);

# output results
print join(' ',@pids)."n";