Ever gotten annoyed at how different from every other subroutine call system is? Ever screwed up your error reporting because you couldn't remember what to do with $?, $@ and $!? I sure have... and I got sick of rewriting this over and over, so I wrapped it in a utility subroutine, and here it is. It assumes the system LIST style is being used, because system SCALAR is somewhat hazardous and (IMO) to be discouraged, but obviously it's readily modified to be more tolerant.

Usage:

wrap_system(qw(perl -u -e 1)) or die "$@\n" #perl exited with status 0 after receiving signal 6 (core dumped)
sub wrap_system { if ( 0 == system { $_[0] } @_ ) { return 1 } if ( -1 == $? ) { $@ = "Unable to launch $_[0]: $!" } else { $@ = "$_[0] exited with status " . ($? >> 8); if (my $sig = $? & 127) { $@ .= " after receiving signal $sig" + } if ($? & 128) {$@ .= " (core dumped)" } } return; }

Replies are listed 'Best First'.
Re: wrap 'system LIST' in a (somewhat) more friendly style
by liz (Monsignor) on Jan 17, 2004 at 13:08 UTC
    I like it. And with a little twist you can use it everywhere just as the normal system():
    BEGIN { *CORE::GLOBAL::system = sub { if ( 0 == CORE::system { $_[0] } @_ ) { return 1 } if ( -1 == $? ) { $@ = "Unable to launch $_[0]: $!" } else { $@ = "$_[0] exited with status " . ($? >> 8); if (my $sig = $? & 127) { $@ .= " after receiving signal $sig" + } if ($? & 128) {$@ .= " (core dumped)" } } return; }; } system(qw(perl -u -e 1)) or die "$@\n";

    Now I wouldn't recommend you'd actually do this, as it will wreak havoc on all modules that expect system() to work the "old" way. But when we get fully controllable lexical pragma's (5.9.1?), then you would be able to do this in your own code without interfering with any other modules (by checking the appropriate pragma in this sub and reverting to the old behaviour if the pragma would not be set).

    Liz