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;
E.g.
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
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 );
Adding to @zigdon's answer:
Lets say your $myNode
is foo
, your regex will be /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/) {
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";
}
精彩评论