Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Killing a shell script from within a perl script

by strider88 (Initiate)
on Mar 03, 2010 at 16:42 UTC ( [id://826451]=perlquestion: print w/replies, xml ) Need Help??

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

I have a perl script that repeatedly runs a shell script within a while loop, as

LOOP1:while($run_count<max) { $shell_out = system("./sh1.sh"); $run_count++; }
Sometimes the shell script takes more time than it is supposed to take(say 10 min), during when I would like to stop the shell script and skip to the next iteration. Could you please tell me how I can achieve this ?

Replies are listed 'Best First'.
Re: Killing a shell script from within a perl script
by jettero (Monsignor) on Mar 03, 2010 at 16:49 UTC

      I tried doing this:

      eval { local $SIG{ALRM}=sub{die "alarm\n"}; alarm 600; $shell_out = system("./sh1.sh"); alarm 0; }; if($@) { die unless $@ eq "alarm\n"; }
      It turns out that the shell script is not even executed.

        The problem with this code is that the shell script isn't being killed.

        alarm just arranges for a signal to be delivered to the Perl process, upon which the signal handler throws an exception (die "alarm\n") which in turn causes the Perl script to continue after the eval {} block. The shell script doesn't know anything of this and happily keeps running.

        It turns out that the shell script is not even executed.

        This is most likely an unrelated problem. Makes me wonder how/why it did run before with the identical system command...

Re: Killing a shell script from within a perl script
by almut (Canon) on Mar 03, 2010 at 17:07 UTC

    You could use open with a pipe in order to get the PID of the child process, and kill it if it doesn't finish in time. Something like this:

    #!/usr/bin/perl my $pid = open my $fh, "your_command ... |" or die $!; eval { local $SIG{ALRM} = sub { die "alarm\n" }; alarm 600; # ... optionally read any output from the subprocess # while (<$fh>) { ... } close $fh; # waits for child alarm 0; }; if ($@ eq "alarm\n") { # timed out kill 9, $pid; }

    Note that if the shell script itself is running further child processes (not that unlikely...), they would not necessarily be killed, too (depends on the behavior/setup of the shell). In that case you'd have to create a process group and kill the entire group in case of timeout. See Re^2: Killing children's of children for sample code.

      I tried this method, but the shell script is not even executed. Why do you think this is happening?

Re: Killing a shell script from within a perl script
by BrowserUk (Patriarch) on Mar 03, 2010 at 17:11 UTC
    #! perl -slw use strict; use threads; use threads::shared; my( $max, $run_count ) = 5; LOOP1:while( $run_count < $max ) { my $end = time() + 10 * 60; my $pid :shared; async { $pid = open SHELL, qq[| ./sh1.sh] or die $!; }->detach; sleep 1 until $pid; sleep 1 while kill 0, $pid and time() < $end; kill 9, $pid; $run_count++; }

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Killing a shell script from within a perl script
by walto (Pilgrim) on Mar 03, 2010 at 17:35 UTC
    An (Linux) approach without threads (not tested):
    LOOP1:while($run_count<max) { my $pid = `pidof sh1.sh`; unless ($pid eq ''){ print "Killing Process sh1.sh PID=$pid\n"; kill $pid; sleep 1; next; } else { $shell_out = system("./sh1.sh"); $run_count++; } }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://826451]
Approved by keszler
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-24 21:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found