Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have come across several commands that use 2>&1 and 1>&2 but 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?
share|improve this question

7 Answers 7

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 fd to the file, and the other fd into the first one:

app 1>/dev/null 2>&1

app 2>/dev/null 1>&2

In the first example, 2>&1 points fd #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 (fd #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 fd goes to the right of >&, and the fd you want to redirect goes to the left. (2>&1 means "point fd #2 to fd #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

share|improve this answer
    
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
1  
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 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
share|improve this answer
    
What do you mean by pipes generally connect standard output to standard input? –  PeanutsMonkey Jun 14 '12 at 0:57
2  
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

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.

share|improve this answer
    
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
    
Thanks. That makes sense. –  PeanutsMonkey Jun 14 '12 at 0:56

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).

e.g.

echo "file \"${file\" does not exist..." 1>&2
share|improve this answer

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>&-
share|improve this answer

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.

share|improve this answer
    
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!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.