Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Find children of process (unix/linux)

by Tanktalus (Canon)
on Jan 26, 2005 at 16:43 UTC ( [id://425266]=sourcecode: print w/replies, xml ) Need Help??
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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://425266]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (1)
As of 2024-04-19 00:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found