ninja
ninja

Reputation: 29

Unable to handle exception handling on a Psexec command in perl

I am trying to exit the for loop if the psexec command fails or more importantly if it takes more time , i am using Time::Out module in this program , but the psexec command does not exit ,am i using it wrong? Is there any other way to deal with this situation.

#$nb_secs means number of seconds
  for my $host1 (@servers){
        timeout $nb_secs => sub {
                 # do stuff that might timeout.
                $returnFileNames=`psexec \\\\$host1 cmd /c "dir /s 
                 d:\\dd\` ;
        }; 

        next if $@;
}

Upvotes: 1

Views: 82

Answers (1)

mob
mob

Reputation: 118665

There are various reasons why a SIGALRM will not get delivered to a process, and you have discovered one of them. A workaround is the poor man's alarm -- run a separate process in the background to monitor the long running process and to kill it after some time has expired. On Windows and with a command where you need to capture the output, it would look something like this:

# $pid is the id of the process to monitor
my $pid = open my $proc_fh, '-|', "psexec \\\\$host1 cmd /c "dir /s d:\\dd\";

my $pma = "sleep 1,kill(0,$pid)||exit for 1..$nb_secs;"
        . "kill -9,$pid;system 'taskkill /f /pid $pid >nul'";
my $pma_pid = system 1, $^X, "-e", $pma;

# read input from the external process.
my $returnFilenames;
while (<$proc_fh>) {
    $returnFilenames .= $_;
}
close $proc_fh;

The poor man's alarm is a little program with two parts. The first part counts up to $nb_secs seconds and terminates if the monitored process is no longer running (if kill 0,$pid returns a false value). The second part of the program, if it is reached, terminates the monitored process. In this instance, we try two different ways (kill -9 ... and system 'taskkill /f ...') to terminate the process.

Upvotes: 1

Related Questions