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

I am trying to port a shell script to perl It was:
/path/to/program/that/would/output/something/and/run/forever > /dev/nu +ll 2>&1 & for i in `seq 1 10`; do sleep 1; echo -n "." done kill -9 $!
The idea is to let the program capture some data and parse its logfile afterwards. So I need to start the program, put it in the background, output something to show I am alive, and kill the programm. However, I couldn't find how to do it.

Replies are listed 'Best First'.
Re: Executing a program, displaying some status, and killing it
by Roy Johnson (Monsignor) on Dec 08, 2004 at 00:47 UTC
    Check out fork and exec. Something like:
    my $child = fork; if ($child) { # I am in the parent...wait then kill for my $i in (1..10) { sleep 1; print "."; } kill -9, $child; } else { # Run the background program exec '/path/to/program/that/would/output/something/and/run/forever > + /dev/null 2>&1'; }
    There is more to error checking for return values than I illustrate here. Do see the documentation for examples.

    Caution: Contents may have been coded under pressure.

      I realize you were probably doing a quick port, but there are a few things I would like to point out.

      • You create an explicit variable with your for loop, but never use it.
      • There is a minor syntax error (for my $i in should just be for my $i).
      • You pass -9 to kill, but this should probably be 9 (the negative signal has a different meaning than it does to the shell command kill).

      Fixing these, I would probably write it as follows:

      my $child = fork; if ($child) { # I am in the parent...wait then kill for (1..10) { sleep 1; print "."; } kill 9, $child; } else { # Run the background program exec '/path/to/program > /dev/null 2>&1'; }

      Update: an alternative method that avoids explicit forking, and perhaps looks a bit more Perlish:

      my $pid = open my $cmdfh, "-|", '/path/to/program' or die "Cannot fork: $!\n"; for ( 1 .. 10 ) { print "."; sleep 1; } kill 9, $pid;
        Both versions work, but not the way I want... the status output (print ".") appears only after the background-program has been killed, which makes it pretty useless...