in reply to Re: capturing stderr of a command, invoked via backticks
in thread capturing stderr of a command, invoked via backticks

Trivia:

The "| cat" part is superfluous. What's more, if you drop it, then you get a little-known feature of Perl to kick in and you have a solution that doesn't require support from the shell. Unfortunately, it isn't implemented in all builds of Perl. So you can avoid the shell when using a Unixy perl but still need the shell to handle "2>&1" for you in other environments (and so this doesn't work on Win98, if you can even find a copy).

If you give Perl a command that contains no shell meta characters, then Perl just splits the command on whitespace and execs the specified program itself, skipping the shell, as if you'd passed a list of parameters to exec. The little-known feature is that if you give a command that only contains two shell meta characters and those are the > and the & in 2>&1 and that is at the end of the command, then Perl strips that off the end, splits the rest up, does a quick dup2(1,2) (which makes STDERR a dup of STDOUT), and execs the specified program directly.

This is a feature of exec in Unixy perls. But Unixy perls implement system and qx by using this same exec code so the feature applies in this case as well.

- tye        

Replies are listed 'Best First'.
Re^3: capturing stderr of a command, invoked via backticks (2>&1)
by erroneousBollock (Curate) on Sep 08, 2007 at 04:45 UTC
    The "| cat" part is superfluous.
    Hmmm, you're right of course. I think I formed the habit from shell-isms like so:
    ./script 2>&1 > file
    In that case, without the |cat STDERR is not redirected to file, but that's probably another of my mis-understandings of the mechanism involved.

    -David

      foo 2>&1 >file is useful but does something other than WYM (what you mean). Order matters. 2>&1 changes STDERR to go where STDOUT currently is and "redirectives" are processed from left to right. So foo 2>&1 >file | bar sends foo's STDOUT to file and foo's STDERR to bar's STDIN. What you want is foo >file 2>&1 which sends both STDOUT and STDERR to file (you have to dup STDERR to match STDOUT after you've redirected STDOUT to the file).

      - tye