Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I need to be able to determine if a certain process, (that contains certain values in the pid line such as contents of $version and "online"), is running by obtaining the PID. In csh, I issue the statment:

pid=`ps -ef | grep $version | grep online| awk '{print $2}'`

If pid is null, then I know the process is not running and I need to restart it.

I am rewriting a number of these csh pgms in perl but am fairly new at this. If I issue the system command, I only seem to get a return of '0'. Any help you can provide is greatly appreciated. Thank you.

Replies are listed 'Best First'.
Re: obtaining pid's in Unix environment
by mojotoad (Monsignor) on Nov 18, 2004 at 15:03 UTC
    Here's more of a perlish way to get what you want, which is what you seemed to be asking for:
    open(PS, "ps -ef |") or die "Problem invoking 'ps': $!\n"; while (<PS>) { next unless /$version/ && /online/; my($pid) = (split)[2]; print "pid $pid\n"; } close(PS);

    Cheers,
    Matt

    P.S. If you want to access the value of $pid outside of the while loop, drop the 'my' but keep the parens, but that will break if there's more than one match:

    while (<PS>) { next unless /$version/ && /online/; ($pid) = (split)[2]; } print "pid $pid\n";
Re: obtaining pid's in Unix environment
by JediWizard (Deacon) on Nov 18, 2004 at 14:55 UTC

    The return value of system is the exit code of the command run. If you want to capture STDOUT from the command, you should use `` (Backticks), or qx//;.

    May the Force be with you
Re: obtaining pid's in Unix environment
by edan (Curate) on Nov 18, 2004 at 15:15 UTC

    You could also look at using a CPAN module: Proc::ProcessTable. While not perfect, it does a good job on most flavors of *nix.

    --
    edan

Re: obtaining pid's in Unix environment
by Corion (Patriarch) on Nov 18, 2004 at 14:56 UTC

    Most likely, Perl interpolates the $2 in your awk invocation. I test Perl scripts that call other programs by printing out the command line and comparing that to my expectations:

    my $command = "ps -ef | grep $version | grep online| awk '{print $2}'" +; print "Invoking: >>>$command<<<\n"; my $output = `$command`;

    Most likely, the output you will see above is not what you want, and you want instead something like:

    my $command = sprintf q(ps -ef | grep %s | grep online| awk '{print $2 +}'), $version; print "Invoking: >>>$command<<<\n"; my $output = `$command`;

    which circumvents the interpolation of variables. There are many other ways to build up $command without interpolating variables.

    Update: Reading JediWizards reply, I realize you're using system - if you want the output of commands, don't use system, use backticks, just like in the shell.

Re: obtaining pid's in Unix environment
by TrekNoid (Pilgrim) on Nov 18, 2004 at 16:30 UTC
    Here's some code that I use to get a list of users/pids, if you ever need to get more than one and then do something with them:

    @proc = `ps -ef | grep $param`; foreach $proc(@proc){ ($userid, $pid, @rest) = split(' ', $proc); print "$userid $pid\n"; }
    Trek