Day 14: What $! The $? (Proc::ChildError)
About the series: perlancar's 2014 Advent Calendar: Introduction to a selection of 24 modules which I published in 2014. Table of contents.
Finding out OS error message in Perl is pretty straightforward: just print out the $! variable. Example:
open my $fh, ">", "somefile" or die "Can't open file: $!";
The $! is pretty magical, it can return an integer (errno) or a string.
However, finding out child error message is not equally straightforward: there needs to be some bit-fiddling involved, which I always forget. To quote the perlvar manpage (or, perldoc -f system):
if ($? == -1) { print "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; } else { printf "child exited with value %d\n", $? >> 8; }
I mean, are we really expected to do this incantation everytime we want to check the status ofsome command we launched using system()? So I wrote Proc::ChildError, which is just the above code packaged as a module. Thus you can say:
system "foo" or die explain_child_error();
As a bonus, the function accepts an option prog, for nicer error message (e.g. explain_child_error({prog=>'foo'}). So instead of:
failed to execute: permission denied died with signal 15, without coredump exited with code 100
You get:
foo failed to execute: permission denied foo died with signal 15, without coredump foo exited with code 100
Small stuffs, but it's just another cognitive load I can shave off.
Leave a comment