in reply to SIGINT in system() with shell metachars

Thanks to the many monks who replied to my post and query. Sleeping on a problem always is good for new insight, and this morning, seeing your many interesting and good suggestions has been very helpful.

Some thoughts and comments and conclusions:

  1. The first thing is that the shell (in Solaris at least) encodes the caught signal in its return code: I haven't yet seen this documented in Solaris manuals anywhere, but it's obvious that this is happening. Hence the signal encoded in the HIGH byte (i.e. the return status code).

  2. The backtick method of calling the shell command might actually be better for my needs here, because if you test this out, when I interrupt my Perl script doing a long shell command using backticks, the Perl script catches the signal, whereas if this is done using the system command, the signal is not caught, except through extra handling of the return codes. Since I need to die when interrupted doing shell commands, the backtick method is probably better.

    The other reason why I was using the system command, is that I wanted to catch the full return codes, AND also capture the output (which I did to a tmp file, and then read the tmp file into a variable, and passed both the return status, and the shell output as output to a wrapper System() subroutine. But $? contains the status of the backticked shell command as well as of the system command, and the shell's output goes to a variable, so in effect I can do the same. And since I won't need to dissect the return status to see if it died from a signal (because Perl catches the signal), it should all be sufficient for my needs.

  3. I like the suggestion to use the shell's trap command. Yes! a very under utilized feature of the shell.

  4. Thanks for the suggestion to use IPC::Run. I'll look at that.

  5. Finally, additional research pointed to the possibility of using the open command and piping the output:
    defined($pid = open(CHILDPROC, "$cmdargs |")) or die "Can't fork: $!"; while(<CHILDPROC>){ # ... }

Thanks again for all the advice.

cheers!
-cadphile