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

I have come across several commands that use 2>&1 and 1>&2, but I quite can't get my head around the purpose of using it and when I should be using it.

What I understand

I know that 1 represents standard out and 2 represents standard error. I understand that 2>&1 combines the output of 2 to 1 and vice versa.

What I don't get

1. When should I be using it?
2. What purpose does it serve?

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

• I had no idea that doing app 1>/dev/null 2>&1 would mean that 2>&1 would point to the file that 1 was already redirecting to. I take it I could just as easily do app > /dev/null &>? – PeanutsMonkey Jun 14 '12 at 1:24
• I am having a hard time understanding the already set up fd goes to the right of >&, and the fd you want to redirect goes to the left. What do you mean by the already set up file descriptor? What does it mean the right of? – PeanutsMonkey Jun 14 '12 at 1:25
• i.imgur.com/x3fnN.jpg – grawity Jun 14 '12 at 8:38
• Sorry unless you were intending to teach me directions, I don't follow the statement you made as previously noted. – PeanutsMonkey Jun 15 '12 at 6:35
• Take each file descriptor redirect one at a time, from left to right, and apply those rules in that order. If you first direct stdout to a file, then redirect stderr to where stdout us now pointing, then stderr and stdout will go to the same file. If you swapped those two redirects around, then you would get different results (redirect stderr to where stdout is going now, then move stdout to point to another file, while stderr continues where it was pointed at). – Jason Aug 4 '14 at 21:14

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  • What do you mean by pipes generally connect standard output to standard input? – PeanutsMonkey Jun 14 '12 at 0:57 • I mean that pipe (|) take the standard output of the first command and connect it to the standard input of the second command. – jpalecek Jun 14 '12 at 1:05 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.

• What do you mean by manipulate? My understanding is that anything redirected to >2 is sent to /dev/null. Or have I completely got it wrong? – PeanutsMonkey Jun 14 '12 at 0:45
• That is not correct. By manipulate I mean pipe it to grep or something similar. See here for an example. – soandos Jun 14 '12 at 0:46

I use it to start a detached job:

someProgram 2>&1 >& my.log &


then I can log out, and someProgram will still be running. The functionality is provided by GNU Screen, tmux and some other programs -- but here it is achieved with none of external dependencies.

• That only works as long as there's no SIGHUP sent to the program. Better use nohup or disown in such cases. – slhck Jul 27 '13 at 22:06
• @slhck: ok. But if I woudn't send SIGHUP to program -- no one will, right? – Adobe Jul 28 '13 at 18:42
• No, the controlling terminal will warn processes of a logout with SIGHUP. In practice, if you run a remote shell through SSH and exit, your process will die as well, for example. – slhck Jul 28 '13 at 18:45
• @slhck: Can't be true: I use it for some couple of years -- I logout of ssh, and the process is still running. – Adobe Jul 28 '13 at 19:36
• I will have to look this up in more detail, but just putting programs into background hasn't worked for me in all cases, and it definitely does not even work on my local machine. Zsh and Bash behave differently here as well, it seems. – slhck Jul 28 '13 at 19:54

Imagine there is a directory named try that has these three files: file file1 and file2.

Now run this command:

cat file file1 file2 file3


The first three files open but cat throws an error while opening the fourth one as it does not exist.

Now run:

cat file file1 file2 file3 1>outfile 2>&1


You will not see any output on the screen: Firstly 1>outfile will redirect the output of the command to outfile and then it will redirect (2>&1) the error thrown while trying to open file3 to outfile.

1>&2 works similarly and redirects the error stream to standard output.

Hope this helps!

Alternative scenario: terminal commands show output into another terminal

Use the tty command in each terminal to identify them:

$tty /dev/pts/0$ tty
/dev/pts/1


Assuming these TTYs, to redirect the first's stdout to the second, run this in the first terminal:

exec 1>/dev/pts/1


Note: Now every command output will show on pts/1

To restore default behavior stdout of pts/0:

exec 1>/dev/pts/0


See this video for a demonstration.

The case when re-directing stderr to stdout has already been covered here (e.g. use it to filter (grep) error messages).

The other case is redirecting stdout to stderr. A common usecase (at least for me) is to send warnings/error messages printed with "echo" (in my shellscripts) to the stderr (so they can catch the attention of the user more easily).

For example,

echo "file \"\${file\" does not exist..." 1>&2