Differences between revisions 1 and 2
Revision 1 as of 2007-05-02 23:47:53
Size: 2790
Editor: redondos
Comment:
Revision 2 as of 2007-11-30 03:06:02
Size: 2806
Editor: GreyCat
Comment: change internal links
Deletions are marked like this. Additions are marked like this.
Line 27: Line 27:
There are times when we really do want {{{2>&1}}} to appear first -- for one example of this, see [#faq40 FAQ 40]. There are times when we really do want {{{2>&1}}} to appear first -- for one example of this, see [:BashFAQ#faq40:FAQ 40].
Line 49: Line 49:
A related question is [#faq47 FAQ #47], which discusses how to send stderr to a pipeline. A related question is [:BashFAQ#faq47:FAQ #47], which discusses how to send stderr to a pipeline.

Anchor(faq55)

Tell me all about 2>&1 -- what's the difference between 2>&1 >foo and >foo 2>&1, and when do I use which?

Bash processes all redirections from left to right, in order. And the order is significant. Moving them around within a command may change the results of that command.

For newbies who've somehow managed to miss the previous hundred or so examples, here's what you want:

foo >file 2>&1          # Sends both stdout and stderr to file.

Now for the rest of you, here's a simple demonstration of what's happening:

foo() {
  echo "This is stdout"
  echo "This is stderr" 1>&2
}
foo >/dev/null 2>&1             # produces no output
foo 2>&1 >/dev/null             # writes "This is stderr" on the screen

Why do the results differ? In the first case, >/dev/null is performed first, and therefore the standard output of the command is sent to /dev/null. Then, the 2>&1 is performed, which causes standard error to be sent to the same place that standard output is already going. So both of them are discarded.

In the second example, 2>&1 is performed first. This means standard error is sent to wherever standard output happens to be going -- in this case, the user's terminal. Then, standard output is sent to /dev/null and is therefore discarded. So when we run foo the second time, we see only its standard error, not its standard output.

There are times when we really do want 2>&1 to appear first -- for one example of this, see [:BashFAQ#faq40:FAQ 40].

There are other times when we may use 2>&1 without any other redirections. Consider:

find ... 2>&1 | grep "some error"

In this example, we want to search find's standard error (as well as its standard output) for the string "some error". The 2>&1 in the piped command forces standard error to go into the pipe along with standard output. (When pipes and redirections are mixed in this way, remember: the pipe is done first, before any redirections. So find's standard output is already set to point to the pipe before we process the 2>&1 redirection.)

If we wanted to read only standard error in the pipe, and discard standard output, we could do it like this:

find ... 2>&1 >/dev/null | grep "some error"

The redirections in that example are processed thus:

  1. First, the pipe is created. find's output is sent to it.

  2. Next, 2>&1 causes find's standard error to go to the pipe as well.

  3. Finally, >/dev/null causes find's standard output to be discarded, leaving only stderr going into the pipe.

A related question is [:BashFAQ#faq47:FAQ #47], which discusses how to send stderr to a pipeline.

BashFAQ/055 (last edited 2014-03-06 17:04:32 by ormaaj)