How can I specify timeout limit for Perl system call?
Solution 1
See the alarm
function. Example from pod:
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
alarm $timeout;
$nread = sysread SOCKET, $buffer, $size;
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n"; # propagate unexpected errors
# timed out
}
else {
# didn't
}
There are modules on CPAN which wrap these up a bit more nicely, for eg: Time::Out
use Time::Out qw(timeout) ;
timeout $nb_secs => sub {
# your code goes were and will be interrupted if it runs
# for more than $nb_secs seconds.
};
if ($@){
# operation timed-out
}
Solution 2
You can use IPC::Run's run method instead of system. and set a timeout.
Solution 3
How about System::Timeout ?
This module extends
system
to allow timeout after the specified seconds.
timeout("3", "sleep 9"); # timeout exit after 3 seconds
Solution 4
I've just used the timeout
command in Perl + Linux before, something you can test like this:
for(0..4){
my $command="sleep $_"; #your command
print "$command, ";
system("timeout 1.1s $command"); # kill after 1.1 seconds
if ($? == -1 ){ printf "failed to execute: $!" }
elsif($?&127 ){ printf "died, signal %d, %scoredump", $?&127, $?&128?'':'no '}
elsif($?>>8==124){ printf "timed out" }
else { printf "child finished, exit value %d", $? >> 8 }
print "\n";
}
Output after 4.317 seconds:
sleep 0, child finished, exit value 0
sleep 1, child finished, exit value 0
sleep 2, timed out
sleep 3, timed out
sleep 4, timed out
The timeout
command is part of all major "normal" Linux distributions a.f.a.i.k, a part of coreutils.
Related videos on Youtube
Lazer
Updated on December 01, 2020Comments
-
Lazer over 3 years
Sometimes my system call goes into a never ending state. To, avoid that I want to be able to break out of the call after a specified amount of time.
Is there a way to specify a timeout limit to
system
?system("command", "arg1", "arg2", "arg3");
I want the timeout to be implemented from within Perl code for portability, and not using some OS specific functions like ulimit.
-
Ether over 13 yearsThis is a duplicate more times than I can count: stackoverflow.com/questions/2679582/… stackoverflow.com/questions/1962985/… stackoverflow.com/questions/2423288/ways-to-do-timeouts-in-perl stackoverflow.com/questions/3427401/… stackoverflow.com/questions/1165316/… are just a few.
-
-
miken32 over 7 yearsLink-only answers are not helpful when content moves or changes. Include the relevant parts of the link in your answered, tailored to match the question.
-
FelixSFD over 7 yearsA link to a potential solution is always welcome, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline. Take into account that being barely more than a link to an external site is a possible reason as to Why and how are some answers deleted?.
-
antred about 7 yearsThis seems to work, but the problem is that the command executed via the system call will continue to run, even if the parent Perl process has already died. Does anyone know how to obtain the process id / handle of the process run by the system call so that we can kill it before the Perl script ends?
-
sger about 7 years
-
dennisjbell about 4 yearsI don't know why this answer isn't higher. For the context of "when running a system call", using a system solution seems apropo, and is simple and direct.
-
Bill McGonigle over 3 yearsPerfect for "perl as glue code". Thanks. Next time I'm writing a perl application, IPC::Run will get a go but this is right when I'm shelling out anyway.