简体   繁体   中英

How can I check if a Unix process is running in Perl?

In UNIX, I am checking to see if a process is up by executing the following command;

Eg

psg dtllst pe99

This returns the following output if the process is running;

UID    PID    PPID    C    STIME    TTY    TIME CMD
pe99   1234   1       0 03:29:44    pts/8  0:01 dtllst pe99

Now in Perl, I want to be able to find out whether this process is up or not. So far I am doing the following

`my $checkProc = `psg dttlst | grep $myNode 2>&1`;`    #where $myNode is something like pe01 or pe02 or pe65 or pe99 etc...

Now after this I do the following to see if the above Perl command has returned what I am looking for to see if the process is up;

if ($checkProc =~ m/dtllst $myNode | $myNode/) {
    #yes, process is up
} else {
    #no, process is down
}

However this is not working - specifically, regardless of whether the UNIX process is alive or not, my code ALWAYS evaluates the if statement as true. I know this is wrong. I have tried to escape the "$" character in the regex to see if this was the issue and I have also tried removing the Perl variables from within the regex altogether.

What am I missing here? I know my regex is wrong somewhere :(

Thanks

You could use Proc::ProcessTable to avoid having to launch an external command and parse its output. Something like

use Proc::ProcessTable;
...
my $t = Proc::ProcessTable->new;
my $is_running = grep { $_->{cmndline} =~ /^dtllst $myNode/ } @{$t->table};

Are you perhaps matching the grep process? You could always add a | grep -v grep | grep -v grep to make sure you're filtering that line out of the ps output.

You could use the kill command, seems a cleaner way;

#!/usr/bin/perl

#-- check if process 11325 is running
$exists = kill 0, 11325;
print "Process is running\n" if ( $exists );

I think I know why it was happening so. Your code always evaluates to true, because the psg command with the pattern you are using will also appear in the list of processes the psg command outputs when that command is invoked from within Perl script. Instead of performing a match in the if-condition to determine whether the process is running or not, you may want to keep a count of matches and treat that the process matching your pattern is running when the count of matches exceeds 1. Here is the piece of code I used:

my $match_count = 0;
my $processes = `ps x`;
while($processes =~ m/(.*?)\n/sg)
{
    my $process = $1;
    chomp($process);
    if($process =~ m/$pattern/)
    {
        #print "$process matched $pattern \n";
        $match_count++;
    }
}

if($match_count > 1)
{
    print "The process is running";
}

Adding to @zigdon's answer:

Lets say your $myNode is foo , your regex will be /dtllst foo | foo/ /dtllst foo | foo/

Now this searches for the string 'dtllst foo ' or ' foo' in $checkProc .

Notice that there is a space after 'foo' in 'dtllst foo ' . The only place this string could be found is in the last column as CMD but the trailing space will cause the match to fail.

Also your alternative ' foo' has a space too. If the only way to find the process is to search for 'dtllst foo' there is no need for this alternative as this alternative will also match 'foo' running as an argument to some other command.

And the regex for which is :

if ($checkProc =~ m/dtllst $myNode/) {

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM