Malavika
Malavika

Reputation: 47

"if" conditions not working as expected

I am seeing two issues with my Perl script:

I am trying to check whether a process is already running, and if so

A simple if test fails too. I have attached example code at the end.

Could some one please let me know the cause of these issues?

if ( `ps -ef | grep example | grep -v grep` ) {

    print "Process is already running\n";

    my $pid = `ps -ef | grep example | grep -v grep | awk '{print \$2}'`;

    if ( `ps -p $pid -o etime= | sed -e "s/:/\\n/g" | wc -l | grep 3` ) {

        print "1. Running for more than 40 mins\n";
        `ps -ef | grep example | grep -v grep | awk '{print \$2}' | xargs kill -9`;
    }
    elsif ( `ps -p $pid -o etime= | sed -e "s/:/\\n/g" | wc -l|grep "2"` ) {

        my $pmin = `ps -p $pid -o etime= | awk -F: '{print \$1}'`;

        if ( $pmin < 30 ) {

            print "Process running for 15 mins. Exiting";
            exit;
        }
        elsif ( $pid >= 40 ) {

            print "2.Running for more than 40 mins\n";
            `ps -ef | grep example | grep -v grep | awk '{print \$2}' | xargs kill -9`;
        }
        else {

            print "Process running for 30 mins. Notify";
        }
    }
}

my $psc = `ps -ef | grep example | grep -v grep >/dev/null 2>&1 && echo "Yes" || echo "No"`; 
print "PSC - $psc"; 

if ( $psc eq "Yes" ) { 
    print "running"; 
} 
else { 
    print "not running"; 
}

./test.pl

PSC - Yes 
not running 

Upvotes: 0

Views: 113

Answers (2)

Senthil Prabu
Senthil Prabu

Reputation: 16

Try the below change

ps -A | grep firefox >/dev/null 2>&1 && echo "Yes" || echo "No"

Upvotes: 0

Sobrique
Sobrique

Reputation: 53508

I think this might be the root of your problem:

elsif ($pid >= 40) {

Because that's the process ID. Not $pmin. So you're basically killing and process ID >40, which will be almost any process, apart from occasionally if it randomly gets a low pid.

But pretty fundamentally - shelling out to ps and grep is painful. Replacing : with \n and then counting lines is a bit of a nasty thing to do - and then using grep to match a string is also pretty dirty.

Why not rewrite using something like Proc::ProcessTable instead?

Here's an example of how you'd read the process table, find a particular process id (or set of) and then query the time:

#!/usr/bin/env perl

use strict;
use warnings;

use Proc::ProcessTable;
use Data::Dumper;

my $ps = Proc::ProcessTable->new;

my @target_processes = grep { $_->pid eq $$ } @{ $ps->table };

print Dumper \@target_processes;

sleep 10;

while (1) {

   foreach my $process ( grep { $_->cmndline =~ m/perl/ } @{ $ps->table } ) {
      sleep 5;
      print $process ->cmndline, " has been running for ",
        $process->time / 10000, "s\n";
      print Dumper \$process;
   }

}

Note - the time is a high res time

Upvotes: 4

Related Questions