I know this has been asked a couple of times before, but please bear with me. I'd like to be able to run shell commands (
system() or
qx()) that time-out after a given time, something like:
$exit = &command( "/bin/snore", 60 );
I pretty new to the world of pipe/fork/exec stuff, so please excuse any ignorance!
I fould this in perlipc:
eval {
local $SIG{ALRM} = sub { die "alarm clock restart" };
alarm 10;
flock(FH, 2); # blocking write lock
alarm 0;
};
if ($@ and $@ !~ /alarm clock restart/) { die }
Along with the quote:
|
If the operation being timed out is system() or qx(), this technique is liable to generate zombies. If this matters to you, you'll need to do your own fork() and exec(), and kill the errant child process.
|
So after a bit of research i came up with this:
#! /usr/bin/perl
use strict;
my $exit = &command( "sleep 4; exit 99;", 1 );
if(! defined( $exit ) ) { print "error: command timed-out\n" }
else { print "yay, it worked, exit: $exit\n" }
sub command
{
my( $command, $timeout ) = @_;
my $pid;
eval
{
local $SIG{ALRM} = sub { die };
if( $pid = fork ) { alarm $timeout }
else { exec( $command ) || die( "Couldn't exec $comma
+nd" ) }
waitpid( $pid, 0 );
alarm 0;
};
if( $@ ) { return undef }
else { return $? / 256 }
}
fork... check
exec... check
kill... ? oops, where do i do this?
Am i still breeding zombies? And how do i go about capturing output? Thanks.
- ><iper
my JAPH:
print"Just another Perl hacker\n";
# ^ look, no space! pretty tricky hey?