Reputation: 29
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
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