ceweldon has asked for the wisdom of the Perl Monks concerning the following question:

I have a script that runs a command and if the command hasn't finished within 10 seconds it send an SNMP trap to our moniotring server. The issue that I amn running into is the command continues to run after the snmp trap has been sent and I want to command to die. I put an example of the script below. The command I have it running will wait for a password to be entered so I know that it will time out, which it does. However, after it times prints the "Command Has timed out" and returns to a prompt if you try and type you get an I/O error that shows that the command was still running. I'm a newb to Perl so any help would be greatly appreciated.
#!/usr/bin/perl -w local $SIG {ALRM} = sub {die "alarm"}; eval { alarm (2); system "$vmdiscover --server esx3-1.erp.ufl.edu --managedentity ho +st --entityname esx3-1.erp.ufl.edu "; alarm (0); }; if ($@ && $@ =~ /^alarm/) { print "Command has timed out"; }

Replies are listed 'Best First'.
Re: Kill a command launched within script
by lostjimmy (Chaplain) on Nov 21, 2008 at 16:47 UTC
    The only thing that comes to mind (but probably isn't really the best solution) is to open the executable as a pipe, then close it after the eval block.
    local $SIG {ALRM} = sub {die "alarm"}; my $fh; eval { alarm (2); open $fh, "-|", "$vmdiscover ..." or die "Couldn't open $vmdiscove +r: $!"; while (<$fh>) {}; alarm (0); }; if ($@ && $@ =~ /^alarm/) { print "Command has timed out"; } elsif ($@) { print "$@\n"; } close $fh;
      In words, not in perl: you fork with open(my $chld, '-|'), in the child you send your PID to the father, and then exec the $vmdiscover thing; in the parent, you read the PID of the child, and after the timeout you just kill it.
      []s, HTH, Massa (κς,πμ,πλ)
Re: Kill a command launched within script
by zwon (Abbot) on Nov 21, 2008 at 18:54 UTC
    You can use fork/exec instead of system like this:
    #!/bin/perl use strict; use warnings; my $pid = fork(); unless ($pid) { exec "nc -l 7777" or die; } local $SIG{ALRM} = sub { print "Command timed out!\n"; kill 9, $pid; }; alarm 2; waitpid $pid, 0; alarm 0;