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

Hi, Can anybody help me how to retreive the error message or number from the system command in perl. Thanks - Muruga
  • Comment on how to retrieve the error message returned by the system command

Replies are listed 'Best First'.
Re: how to retrieve the error message returned by the system command
by diotalevi (Canon) on Mar 24, 2006 at 19:41 UTC

    Here's the documentation on $? from perlvar

    The status returned by the last pipe close, backtick (``) command, successful call to wait() or waitpid(), or from the system() operator. This is just the 16-bit status word returned by the wait() system call (or else is made up to look like it). Thus, the exit value of the subprocess is really ("$? >> 8"), and "$? & 127" gives which signal, if any, the process died from, and "$? & 128" reports whether there was a core dump. (Mnemonic: similar to sh and ksh.)

    Also see "Error Indicators".

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re: how to retrieve the error message returned by the system command
by Roy Johnson (Monsignor) on Mar 24, 2006 at 19:43 UTC
    The exit code (number) is encoded in $?. The message is not available, because it's merely part of whatever program you ran. You could try capturing STDERR from it.

    Caution: Contents may have been coded under pressure.
Re: how to retrieve the error message returned by the system command
by wazoox (Prior) on Mar 25, 2006 at 15:55 UTC
    The more elegant option is to use IPC::Run3 instead of system. It allows you to grab the STDERR of the program you run.
    The quick and dirty way is to use a temporary file (it's fine if you need to use only core modules), however it will spawn a shell and probably will be much slower than IPC::Run3.
    The other "good" option using core modules only would be using IPC::Open3, however this one is so tricky to use that it's close to unusable and extremely bug-prone, I wouldn't use it anymore because it's so difficult to get right...
Re: how to retrieve the error message returned by the system command
by njcodewarrior (Pilgrim) on Mar 25, 2006 at 14:05 UTC

    If you're running on a *nix OS, you could redirect the standard error to a temporary file and then parse the contents if it the file exists.

    my $ERR_FILE = q{/tmp/error_message.txt}; qx{COMMAND 2>$ERR_FILE}; if ( -f $ERR_FILE ) { open my $FH, '<', $ERR_FILE; my @err_msg = <$FH>; close $FH; unlink $ERR_FILE or die "Can't remove $ERR_FILE: $!"; }
    --njcodewarrior

      You can do the same thing (with pretty much the same syntax) on modern versions of Windows. I'd use File::Temp; and one of the mktemp family of functions to generate a name, but that's more a style issue than a real difference.

      emc

      " The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents."
      —Nathaniel S. Borenstein