[Chicago-talk] Script design question

Young, Darren Darren.Young at ChicagoGSB.edu
Fri Dec 16 14:30:23 PST 2005

Thanks, I've been looking at using one or more of the suggestions here,
thanks for the input!

Have a few questions though.

> #!perl
> use strict;
> use warnings;
> use POSIX ":sys_wait_h"; # Not sure if you need this.
> my ($pid1, $pid2);
> if( ($pid1 = fork()) == 0 ) {
>      sleep 10;
>      print "child 1\n";
>      exit 69;
> }
> if( ($pid2 = fork()) == 0 ) {
>      print "child 2 execs `date`\n";
>      exec("date") or die "error executing `date`!\n";
>      # exec never returns on success

At this point in the example, using system() wouldn't be a good idea
since it does a fork() itself correct

Also, how can I deal with grabbing stdout and stderr from what exec()
produced? Should I just dup those at the beginning of the script to a
logfile as in: 

    open( STDOUT, ">>$LOGFILE" ) or die "Unable to dup STDOUT: ($!)\n";
    open( STDIN,  "/dev/null" )  or die "Can't read /dev/null: ($!)";
    open( STDERR, ">>&STDOUT" )  or die "Can't dup stdout: ($!)";

What if a the command exec()'d exits with values other than just true or
false? How could that be reached and passed upstream? In your example,
you examined $? in the while($kid) loop, is the '$? / 256' the return
value from the exec() call or the command that exec() in fact executed?
If it is in fact the return from the exec()'d command, is that because
you have no explicit exit() in that portion and $? is set to the value
of the last expression (like what happens at the end of a sub)?

The perldoc for exec() says: "It fails and returns false only if the
command does not exist and it is executed directly instead of via your
system's command shell"

So, it seems that exec() returns false *only* when that particular
condition is met. So if I tried to exec('/foo/bar/cmd') and it doesn't
exist, it will come back false. If however, /foo/bar/cmd returns say, 32
exec() still comes back with true. Reason I ask is that I know some of
the iPlanet utilities have return codes other than 0 or 1 that indicate
"transient" error conditions.

What if I used something like open3 inside the fork() to obtain access
to STDIN, STDOUT and STDERR individually? Doesn't sound like a good idea
to me, but I've never tried it.

> }
> my $kid;
> # Blocking waitpid.
> while( ($kid = waitpid(-1, 0)) != -1 ) {
>      my $status = $? / 256;
>      if ( $kid == $pid1 ) {
>          print "Child 1 exited with status $status\n";
>      }
>      elsif ( $kid == $pid2 ) {
>          print "Child 2 exited with status $status\n";
>      }
>      else {
>          die "Got unexpected child pid. Shouldn't happen.\n";
>      }
> }

More information about the Chicago-talk mailing list