Why redirect output to 2>&1 and 1>&2?

Sometimes you want to redirect both stdout and stderr to the same location, This is when >& is used – it points one file descriptor to another.


For example, if you want to write both stdout and stderr to the same file (be it /dev/null or output.txt), you can redirect them separately, with

app 1>/dev/null 2>/dev/null

or you could redirect one file descriptor to the file, and the other file descriptor into the first one:

app 1>/dev/null 2>&1

app 2>/dev/null 1>&2

In the first example, 2>&1 points file descriptor #2 to where #1 is already pointing. The second example achieves the same, just starting with stderr instead.

As another example, there are cases when stdout (file descriptor #1) is already pointing to the desired location, but you cannot refer to it by name (it may be associated with a pipe, a socket, or such). This often happens when using process expansion (the ` ` or $( ) operators), which normally only captures stdout, but you may want to include stderr in it. In this case, you would also use >& to point stderr to stdout:

out=$(app 2>&1)

Another common example is a pager, or grep, or similar utility, since the pipe | normally only works on stdout, you would redirect stderr to stdout before using the pipe:

app 2>&1 | grep hello

How to know which of 2>&1 or 1>&2 is correct? The already set up file descriptor goes to the right of >&, and the file descriptor you want to redirect goes to the left. (2>&1 means "point file descriptor #2 to file descriptor #1".)


Some shells have shortcuts for common redirections; here are examples from Bash:

  • 1> can be shortened to just >

  • 1>foo 2>&1 to >&foo or &>foo

  • 2>&1 | program to |& program


One situation when you need it is when you want to display strace output in a pager. strace prints its output to standard error and pipes generally connect standard output to standard input, so you have to use the redirect:

strace -p $pid 2>&1 | less

Sometimes you want to redirect both stdout (1) and stderr (2) to the same location (/dev/null, for example). One way of achieving this would be:

$ program 1>/dev/null 2>/dev/null

But most people shorten this by redirecting stderr to stdout with 2>&1:

$ program 1>/dev/null 2>&1

An even shorter version is:

$ program >&- 2>&-

2: It is for when you will have output coming from both standard error and standard out, and you want them composed into a single string.

1: When you want to manipulate the output of both standard error and standard out.