Category: Utility Scripts
Author/Contact Info Tanktalus@gmail.com
Description: Prints out all the child processes of a given process ID. The tough part is that ps is inconsistant across unix platforms.
#!/usr/bin/perl -w

#use Data::Dumper;
use strict;

my %order;
set_order();

my @process_list;
get_processes();

my $parent = shift || parent_of($$);
print "Children of PID $parent:\n";

my @children = grep { $_->[$order{PPID}] == $parent and $_->[$order{PI
+D}] != $$ } @process_list;
foreach my $c (@children)
{
    print $c->[$order{PID}], " : ", $c->[$order{CMD}], "\n";
}

sub parent_of
{
    my $pid = shift || return -1;
    for (my $i = 0; $i <= $#process_list; ++$i)
    {
        return $process_list[$i][$order{PPID}]
            if ($process_list[$i][$order{PID}] == $pid);
    }
    return -1;
}

sub process_info
{
    my $pid = shift || return -1;
    for (my $i = 0; $i <= $#process_list; ++$i)
    {
        return $process_list[$i] if ($process_list[$i][$order{PID}] ==
+ $pid);
    }
    return -1;
}

sub get_processes
{
    local *FH;
    my $opts = "-ef";
    if (
        $^O eq "linux"
       )
    {
        $opts .= " --cols 1024";
    }

    open (FH, "ps $opts |") or die "Can't get process list";
    my $discard = <FH>;
    while (<FH>)
    {
        chomp;
        s/^\s+//;
        my @line = split /\s+/, $_, scalar keys %order;
        push @process_list, \@line;
    }
    close(FH);
}

sub set_order
{
    if (
        $^O eq "aix" or
        $^O eq "irix" or
        $^O eq "hpux"
       )
    {
        %order = (
                  UID => 0,
                  PID => 1,
                  PPID => 2,
                  C => 3,
                  STIMEM => 4,
                  STIMED => 5,
                  TTY => 6,
                  TIME => 7,
                  CMD => 8,
                 );
    }
    elsif (
           $^O eq "dynixptx" or
           $^O eq "linux"
          )
    {
        %order = (
                  UID => 0,
                  PID => 1,
                  PPID => 2,
                  C => 3,
                  STIME => 4,
                  TTY => 5,
                  TIME => 6,
                  CMD => 7,
                 );
    }
    else
    {
        die "Unrecognised platform";
    }
}
Replies are listed 'Best First'.
Re: Find children of process (unix/linux)
by idsfa (Vicar) on Jan 27, 2005 at 02:46 UTC

    Consider Proc::ProcessTable. You may want to look into porting that to any unsupported OS ...

    use strict; use Proc::ProcessTable; my $tgt = shift || $$; my %cmd; my %children; my $pt = new Proc::ProcessTable or die("No process table "); sub treeprint { my ($pid, $indent) = @_; print ' ' x $indent,"$pid: $cmd{$pid}\n"; # What the heck ... let's recurse to the end of the tree foreach (@{$children{$pid}}) { &treeprint($_, $indent+1); } } foreach my $proc ( @{$pt->table} ) { push @{$children{$proc->ppid}}, $proc->pid; $cmd{$proc->pid} = $proc->cmndline; } &treeprint($tgt,0);

    The intelligent reader will judge for himself. Without examining the facts fully and fairly, there is no way of knowing whether vox populi is really vox dei, or merely vox asinorum. -- Cyrus H. Gordon