http://qs1969.pair.com?node_id=1105535


in reply to Re^2: capturing stderr of echo piped to a file
in thread capturing stderr of echo piped to a file

Perhaps you should just try it?

> { echo out; echo err >&2; } >f1 2>&1 > cat f1 out err > { echo out; echo err >&2; } 2>&1 >f1 err > cat f1 out

Redirection order definitely DOES matter in the shell. (Hmm, unless it's shell-specific? I'm using bash)

And just to do exactly what you said..

> perl -e'print "print\n"; warn "warn"' >f1 2>&1 > cat f1 warn at -e line 1. print > perl -e'print "print\n"; warn "warn"' 2>&1 >f1 warn at -e line 1. > cat f1 print

In the first case both print and warn go to the file, in the second case warn goes to stdout and print to the file.

Replies are listed 'Best First'.
Re^4: capturing stderr of echo piped to a file
by boftx (Deacon) on Oct 29, 2014 at 19:26 UTC
    ~/stuff > perl foobar.pl Normal STDOUT Going to STDERR ~/stuff > echo 'Just a starting point > ' >JGBtest.txt ~/stuff > cat JGBtest.txt Just a starting point ~/stuff > perl foobar.pl >>JGBtest.txt 2>&1 ~/stuff > cat JGBtest.txt Just a starting point Going to STDERR Normal STDOUT ~/stuff > cat foobar.pl #!/usr/bin/perl use warnings; use strict; print "Normal STDOUT\n"; warn "Going to STDERR\n"; exit; __END__ ~/stuff >
    You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

      You didn't run the test with reversed redirection, so the above doesn't actually show anything new. Here's what I get with your code, including also a reversed order test:

      ~> perl foobar.pl Normal STDOUT Going to STDERR ~> echo 'Just a starting point > > ' >JGBtest.txt ~> cat JGBtest.txt Just a starting point > ~> perl foobar.pl >>JGBtest.txt 2>&1 ~> cat JGBtest.txt Just a starting point > Going to STDERR Normal STDOUT ~> perl foobar.pl 2>&1 >>JGBtest.txt Going to STDERR ~> cat foobar.pl #!/usr/bin/perl use warnings; use strict; print "Normal STDOUT\n"; warn "Going to STDERR\n"; exit; __END__ ~>

      Which again shows that the redirection order does matter, and in the 2>&1 >>file case, STDERR goes to the output, not the file.

      Update: And just to illustrate it in one more way...

      ~> perl foobar.pl >>JGBtest.txt 2>&1 & [1] 22571 ~> ll /proc/22571/fd total 0 lrwx------ 1 user group 64 2014-10-29 16:31 0 -> /dev/pts/11 l-wx------ 1 user group 64 2014-10-29 16:31 1 -> /home/user/JGBtest.tx +t l-wx------ 1 user group 64 2014-10-29 16:31 2 -> /home/user/JGBtest.tx +t ~> perl foobar.pl 2>&1 >>JGBtest.txt & [2] 22578 ~> ll /proc/22578/fd total 0 lrwx------ 1 user group 64 2014-10-29 16:32 0 -> /dev/pts/11 l-wx------ 1 user group 64 2014-10-29 16:32 1 -> /home/user/JGBtest.tx +t lrwx------ 1 user group 64 2014-10-29 16:32 2 -> /dev/pts/11 ~> cat foobar.pl #!/usr/bin/perl sleep(100);

        Okay I stand corrected in that order matters. That said, I honestly can't remember ever seeing 2>&1 not coming at the end of the command line, probably because doing so seems to indicate that it won't be captured to STDOUT as one desires.

        ~/stuff > cat JGBtest.txt Just a starting point ~/stuff > perl foobar.pl 2>&1 >>JGBtest.txt Going to STDERR ~/stuff > cat JGBtest.txt Just a starting point Normal STDOUT ~/stuff > perl foobar.pl 2>&1 >>JGBtest.txt | grep STD Going to STDERR ~/stuff > perl foobar.pl 2>&1 | grep STD Going to STDERR Normal STDOUT ~/stuff >

        With all of the foregoing comments by both you and me in mind, I think you're first comment implies that it must come first in order to be captured. But in the interest of being complete even if I'm wrong, I included the final tests that does actually demonstrate what is happening on the command line (though it is not intuitive.) Also, it is possible that setting $| = 1; might alter the output ordering.

        You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.