Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Re: STDOUT STDERR and response code from external Linix command

by mr.nick (Chaplain)
on Jan 04, 2012 at 21:21 UTC ( [id://946295] : note . print w/replies, xml ) Need Help??

in reply to STDOUT STDERR and response code from external Linix command

Something like this?
[a209624@cdrzw2051 ~]$ cat my $cmd="lessss"; my $ret=`sh -e '$cmd' 2>&1`; print "$cmd = $ret = $?\n"; [a209624@cdrzw2051 ~]$ perl lessss = sh: lessss: No such file or directory = 256

mr.nick ...

Replies are listed 'Best First'.
Re^2: STDOUT STDERR and response code from external Linix command
by Eliya (Vicar) on Jan 04, 2012 at 21:49 UTC
    my $ret=`sh -e '$cmd' 2>&1`;

    Didn't you mean -c ?

    for my $cmd ('date', 'dat', 'date -foo') { print "cmd: $cmd\n"; my $out = `sh -c '$cmd' 2>&1`; my $rc = $? >> 8; print "out: $out"; print "rc: $rc\n\n"; } __END__ cmd: date out: Wed Jan 4 22:40:20 CET 2012 rc: 0 cmd: dat out: sh: dat: not found rc: 127 cmd: date -foo out: date: `oo': No such file or directory rc: 1

      Could you pls explain why I need open one more shell?

      Do I need to do the same when calling external scripts(perl,python) ?

        There is no extra shell being called.   While it's normally the shell that does the 2>&1 redirection, Perl is doing some optimisations to not call the shell when it can be avoided.  For example, in the above case, when you say my $out = `date 2>&1`, Perl does the redirection itself, and execs date directly.  When you, however, specify an executable which isn't found, nothing is being executed at all — which is why you don't get the shell's error message in this case.

        In case you want to see the shell's error message no matter what, you have to either call it explicitly (as done above), or put something in the command line that keeps Perl from making the optimisation, e.g. a semicolon (shell meta-character).  In other words, the following two snippets would have the same net effect

        my $out = `sh -c dat 2>&1`; my $out = `dat ; 2>&1`; # prevent optimisation

        i.e. in both cases you'd capture the error message of the shell.  While in this case

        my $out = `dat 2>&1`;

        nothing would be executed at all, and consequently, nothing captured either.