Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Unable to grab STDERR from a backtick command

by reasonablekeith (Deacon)
on Mar 05, 2010 at 11:26 UTC ( [id://826946]=perlquestion: print w/replies, xml ) Need Help??

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

As per the title, I can't seem to get STDERR into the result from a backtick command. Case in point...
#!/local/home/myuser/projects/installs/perl5.10.1/bin/perl my $cmd = "echddo 'arghh'"; my $cmd_result = `$cmd 2>&1`; my $cmd_rc = $?; print "CMD : >>$cmd<<\n"; print "RETURN_CODE: >>$cmd_rc<<\n"; print "CMD_RESULT : >>$cmd_result<<\n"; ------- Which when run gives... myuser@myserver./exec_test.pl sh: echddo: not found CMD : >>echddo 'arghh'<< RETURN_CODE: >>256<< CMD_RESULT : >><<
I did compile perl myself, is it possible I messed it up? Any pointers appreciated, Ta, Rob

Replies are listed 'Best First'.
Re: Unable to grab STDERR from a backtick command
by almut (Canon) on Mar 05, 2010 at 12:29 UTC

    I think it depends on at what exact point the shell is doing the 2>&1 redirection.

    I can't reproduce the problem with the command you've shown, i.e. here I do get

    $ ./826946.pl CMD : >>echddo 'arghh'<< RETURN_CODE: >>32512<< CMD_RESULT : >>sh: echddo: not found <<

    but when I remove one single quote ($cmd = "echddo arghh'"), so the shell command has a syntax error, I get like you

    $ ./826946.pl sh: Syntax error: Unterminated quoted string CMD : >>echddo arghh'<< RETURN_CODE: >>512<< CMD_RESULT : >><<

    The corresponding straces reveal that the redirection simply isn't being done in the latter case (note the missing dup2(1,2) ), presumably because my shell does the syntax checking before the 2>&1 redirection (which makes sense...), while in the other case, it does the redirection before starting to look for an executable 'echddo':

    ( cmd: echddo 'arghh' 2>&1 ) ... [pid 15950] rt_sigaction(SIGTERM, NULL, {SIG_DFL}, 8) = 0 [pid 15950] rt_sigaction(SIGTERM, {SIG_DFL}, NULL, 8) = 0 [pid 15950] fcntl(2, F_DUPFD, 10) = 10 [pid 15950] close(2) = 0 [pid 15950] fcntl(10, F_SETFD, FD_CLOEXEC) = 0 [pid 15950] dup2(1, 2) = 2 [pid 15950] stat("/home/almut/bin/echddo", 0x7fffb62454b0) = -1 ENOENT + (No such file or directory) [pid 15950] stat("/usr/local/sbin/echddo", 0x7fffb62454b0) = -1 ENOENT + (No such file or directory) [pid 15950] stat("/usr/local/bin/echddo", 0x7fffb62454b0) = -1 ENOENT +(No such file or directory) [pid 15950] stat("/usr/sbin/echddo", 0x7fffb62454b0) = -1 ENOENT (No s +uch file or directory) [pid 15950] stat("/usr/bin/echddo", 0x7fffb62454b0) = -1 ENOENT (No su +ch file or directory) [pid 15950] stat("/sbin/echddo", 0x7fffb62454b0) = -1 ENOENT (No such +file or directory) [pid 15950] stat("/bin/echddo", 0x7fffb62454b0) = -1 ENOENT (No such f +ile or directory) [pid 15950] write(2, "sh: ", 4) = 4 [pid 15950] write(2, "echddo: not found", 17) = 17 [pid 15950] write(2, "\n", 1) = 1 ... ( cmd: echddo arghh' 2>&1 ) ... [pid 15945] rt_sigaction(SIGTERM, NULL, {SIG_DFL}, 8) = 0 [pid 15945] rt_sigaction(SIGTERM, {SIG_DFL}, NULL, 8) = 0 [pid 15945] write(2, "sh: ", 4sh: ) = 4 [pid 15945] write(2, "Syntax error: Unterminated quote"..., 40Syntax e +rror: Unterminated quoted string) = 40 [pid 15945] write(2, "\n", 1 ...

    What shell are you using?  (bash v3.2.39 here)

    Your version seems to be trying to find the binary for 'echddo' before having set up the redirection...

      A little-known (and perhaps undocumented) feature of Perl is that a trailing "2>&1" on a command will be handled by Perl itself (not the shell) if there is no other reason to use a shell (if there are no other shell metacharacters in the given command string). (At least that was true quite a while ago when I was reading some of the Perl source code and I don't expect such a feature to be removed.)

      So this problem would go away if the (useless) single quotes were removed from the example $cmd string. Yes, that "fix" likely won't work for the real problem.

      I find it unfortunate that there is no way to trigger this feature when passing a list to system.

      Update: Note that there are several modules to choose from that do "IPC" or "run commands" that can handle the "2>&1" for you. Or you can just handle it yourself using open (the 'fork' and 'dup' forms) and exec. Maybe I'll post an example of doing that in a reply, since I'd have to reread a few things to be able to write such.

      - tye        

      GNU bash, version 2.05.0(1)-release (sparc-sun-solaris2.9)

      I'm guessing that's quite old then.

      I've also have another perl install on here, and am able to reproduce the error using that, so this doesn't look specific to the install I did.

      Thanks,

      Rob

      ---
      my name's not Keith, and I'm not reasonable.
Re: Unable to grab STDERR from a backtick command
by ZlR (Chaplain) on Mar 05, 2010 at 12:32 UTC
    It works for me :

    >perl -w t.pl CMD : >>echddo 'arghh'<< RETURN_CODE: >>256<< CMD_RESULT : >>'echddo' is not recognized as an internal or external c +ommand, operable program or batch file. <<

    (activeperl 5.10 on windows XP)

Re: Unable to grab STDERR from a backtick command
by tbartold (Initiate) on Oct 29, 2010 at 18:08 UTC

    I have the same problem with perl 5.10.1 under linux, but not with the original code, that works:

    CMD : >>echddo 'arghh'<< RETURN_CODE: >>32512<< CMD_RESULT : >>sh: echddo: command not found <<

    However, I want to trap an error from a simple command, but a bad one. For example, a misspelled command:

    my $cmd = "hostnam";

    Here I can't trap the error:

    CMD : >>hostnam<< RETURN_CODE: >>-1<< CMD_RESULT : >><<

    The odd thing is that if I redirect STDOUT/STDERR to a file instead, the error is redirected as expected.

    `$cmd 1>./tmp 2>&1`; my $cmd_rc = $?; my $cmd_result = `cat ./t`;
    CMD : >>hostnam<< RETURN_CODE: >>32512<< CMD_RESULT : >>sh: hostnam: command not found <<

    Is there a better way to get the expected behavior without resorting to a file?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (6)
As of 2024-03-28 08:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found