in reply to Re: Better way to search in the process table?
in thread Better way to search in the process table?

Hello kcott and thank you very much for your elegant solution!

Here is what i worked out:

#!/usr/bin/perl use strict; use warnings; use Proc::ProcessTable; use Data::Dump; my $processes = new Proc::ProcessTable; my $ancestry = 3; my %tree; my %all; for ( @{ $processes->table } ) { $all{ $_->pid } = $_; $tree{ $_->pid } = [$_] if $_->cmndline =~ /^\/usr\/sbin\/mysqld/; } # dd \%all; exit; # dd \%tree; exit; for my $child (keys %tree) { print qq(child:\t$child\n); my $ppid = $all{$child}->ppid; print qq(ppid:\t$ppid\n); for (1 .. $ancestry) { push @{$tree{$child}}, $all{$ppid}; $ppid = $all{$ppid}{ppid}; last unless $ppid; print qq(ppid:\t$ppid\n); } } dd \%tree; __END__

This seems to work.

child: 9675 ppid: 9473 ppid: 1 { 9675 => [ bless({ cmajflt => 0, cminflt => 0, cmndline => "/usr/sbin/mysqld --basedir=/ --datadir=/var/lib/mys +ql --user=mysql --log-error=/var/lib/mysql/Vit-DB-Test1.err --open-fi +les-limit=8192 --pid-file=/var/lib/mysql/Vit-DB-Test1.pid --port=3306 +", cstime => 0, ctime => 0, cutime => 0, cwd => "/var/lib/mysql", egid => 105, euid => 60, exec => "/usr/sbin/mysqld", fgid => 105, flags => 8397056, fname => "mysqld", fuid => 60, gid => 105, majflt => 1, minflt => 1078212, pctcpu => " 0.00", pctmem => 9.46, pgrp => 8146, pid => 9675, ppid => 9473, priority => 16, rss => 1593077760, sess => 8146, sgid => 105, size => 13302890496, start => 1391382138, state => "sleep", stime => 10740000, suid => 60, time => 51560000, ttydev => "", ttynum => 0, uid => 60, utime => 40820000, wchan => -1, }, "Proc::ProcessTable::Process"), bless({ cmajflt => 0, cminflt => 43760, cmndline => "/bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mys +ql --pid-file=/var/lib/mysql/Vit-DB-Test1.pid", cstime => 430000, ctime => 500000, cutime => 70000, cwd => "/", egid => 0, euid => 0, exec => "/bin/bash", fgid => 0, flags => 8388864, fname => "mysqld_safe", fuid => 0, gid => 0, majflt => 0, minflt => 2691, pctcpu => " 0.00", pctmem => 0.01, pgrp => 8146, pid => 9473, ppid => 1, priority => 25, rss => 1527808, sess => 8146, sgid => 0, size => 8228864, start => 1391382137, state => "sleep", stime => 20000, suid => 0, time => 20000, ttydev => "", ttynum => 0, uid => 0, utime => 0, wchan => -2146210175, }, "Proc::ProcessTable::Process"), bless({ cmajflt => 2747, cminflt => 657582982, cmndline => "init [3] ", cstime => 8683530000, ctime => 80500550000, cutime => 71817020000, cwd => "/", egid => 0, euid => 0, exec => "/sbin/init", fgid => 0, flags => 8397056, fname => "init", fuid => 0, gid => 0, majflt => 3, minflt => 3162, pctcpu => " 0.00", pctmem => "0.00", pgrp => 0, pid => 1, ppid => 0, priority => 16, rss => 315392, sess => 0, sgid => 0, size => 819200, start => 1378449866, state => "sleep", stime => 800000, suid => 0, time => 800000, ttydev => "", ttynum => 0, uid => 0, utime => 0, wchan => 0, }, "Proc::ProcessTable::Process"), ], }

If $ancestry == 3 and i don't say last unless $ppid, it goes back until PID 0 and sets one key in %tree to undef. I hope i didn't miss something.

Thanks again for sharing your knowledge and best regards,

Karl

«The Crux of the Biscuit is the Apostrophe»

Replies are listed 'Best First'.
Re^3: Better way to search in the process table?
by kcott (Archbishop) on Mar 03, 2014 at 18:56 UTC
    "If $ancestry == 3 and i don't say last unless $ppid, it goes back until PID 0 and sets one key in %tree to undef. I hope i didn't miss something."

    The keys in %tree are unaffected by that statement: they're already set and you're looping through them (i.e. for my $child (keys %tree) {...}). You'll need to clarify this. You're probably referring to one of these: the value of the key (normally an arrayref); an element in that arrayref (normally a hashref); a key/value in one of those hashrefs.

    I'd normally expect the parent of PID 0 to be PID 0 also. That's true for my OS but perhaps it's not the case on your OS. It's possible that Proc::ProcessTable does not return information for PID 0: I claim no particular experise with this module, you'll need to research this yourself. It could also be a security feature: maybe only UID 0 (root) can query PID 0.

    If the code you currently have does what you want, perhaps just keep to the old adage: "If it ain't broke, don't fix it." :-)

    -- Ken

      "...they're already set"

      Yes. D'oh! I don't known why i wrote this nonsens :-(

      # output shortend $anchestry =3 ; # last unless $ppid; { 9675 => [ bless({ cmndline => "/usr/sbin/mysqld", pid => 9675, ppid => 9473, }, "Proc::ProcessTable::Process"), bless({ cmndline => "/bin/sh /usr/bin/mysqld_safe", pid => 9473, ppid => 1, }, "Proc::ProcessTable::Process"), bless({ cmndline => "init [3] ", pid => 1, ppid => 0, }, "Proc::ProcessTable::Process"), undef, <-- last slot ], } $anchestry = 3 ; last unless $ppid; { 9675 => [ bless({ cmndline => "/usr/sbin/mysqld", pid => 9675, ppid => 9473, }, "Proc::ProcessTable::Process"), bless({ cmndline => "/bin/sh /usr/bin/mysqld_safe", pid => 9473, ppid => 1, }, "Proc::ProcessTable::Process"), bless({ cmndline => "init [3] ", pid => 1, ppid => 0, }, "Proc::ProcessTable::Process"), ], # OK }

      It works.

      Thank you and best regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

      I'll post tomorrow what i figured out because i don't have access to this machine tonight.

      Best regards and thank you, Karl

      «The Crux of the Biscuit is the Apostrophe»