Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
There's more than one way to do things
 
PerlMonks  

Capture external program return value

by llancet (Friar)
on May 02, 2010 at 01:50 UTC ( #837969=perlquestion: print w/ replies, xml ) Need Help??
llancet has asked for the wisdom of the Perl Monks concerning the following question:

I'my attempting to call an program inside perl, and get its stdout:
my $result = `blastall -i foo -o bar -p blastx -d baz`; if ($!) { die "something bad happened: $!"; }

However, the program always die, even if blastall seems to be working properly. It seems that $! only stores something stderr, but not always critical.

So, how should I get the return value properly? Should I use:

eval { $result = `......`; } if ($@) { die "......"; }
instead?

Comment on Capture external program return value
Select or Download Code
Re: Capture external program return value
by ikegami (Pope) on May 02, 2010 at 01:54 UTC
    You cannot determine whether an error occurred or not based on whether $! is not because $! is meaningless if no error occurred.

    eval won't help as it catches exceptions and backticks do not throw exceptions.

    Backticks are documented to return undef on error, so what you need is

    my $result = `blastall -i foo -o bar -p blastx -d baz`; die("Could not execute blastall: $!\n") if !defined($result);
      Backticks are documented to return undef on error
      And to further clearify, that's errors regarding the execution of the given program. The OP also mentions getting the return value - a non-zero exit code means (by convention) that the executed program encountered an error. In that case, backticks will not return undef. However, even backticks set $?, so the return value can be found as $? >> 8.
        my $result = `blastall -i foo -o bar -p blastx -d baz`; die("Could not execute blastall: $!\n") if !defined($result); die("Died from signal ", ($? & 127), "\n") if $? & 127; die("Exited with error ", ($? >> 8), "\n") if $? >> 8;
Re: Capture external program return value
by tokpela (Chaplain) on May 02, 2010 at 04:05 UTC

    IPC::Run3 will allow you to capture the output as well as the return code from the program you are running.

    Untested late night code ;-)

    use strict; use warnings; use IPC::Run3; my ($in, $out, $err); my @cmd = qw{blastall -i foo -o bar -p blastx -d baz}; eval { run3 \@cmd, \$in, \$out, \$err); } if ($@) { die "[Error] Command encountered an error in IPC::Run3 [$@]\n"; } if ($?) { die "[Error] Command encountered an error [$?]\n"; }

    From the docs...

    run3 throws an exception if the wrapped system call returned -1 or anything went wrong with run3's processing of filehandles. Otherwise it returns true. It leaves $? intact for inspection of exit and wait status.

    Note that a true return value from run3 doesn't mean that the command had a successful exit code. Hence you should always check $?.

    Updated with Perlbotics and Hue-Bond suggested use of qw{}.

      Untested late night code ;-)
      my @cmd = ('blastall -i foo -o bar -p blastx -d baz');

      On Sunday morning ;^), this would look better if spelled like this:

      my @cmd = qw{blastall -i foo -o bar -p blastx -d baz};

       

      Edit: removed unneeded parens.

      --
       David Serrano
       (Please treat my english text just like Perl code, i.e. feel free to notify me of any syntax, grammar, style and/or spelling errors. Thank you!).

Re: Capture external program return value
by doug (Pilgrim) on May 02, 2010 at 14:52 UTC

    The details are in perlvar in the description of $?. If you don't know this yet, then you are an absolute beginner, and you should study this section carefully. There are some gotchas with interpreting the value that never seem to make sense to non-hardcore *ix geeks.

    - doug

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://837969]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (10)
As of 2014-04-18 18:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (471 votes), past polls