tags:

views:

11566

answers:

8

In a unix shell, if I want to combine stderr and stdout into the stdout stream for further manipulation, I can append the following on the end of my command:

2>&1

So, if I want to use "head" on the output from g++, I can do something like this:

g++ lots_of_errors 2>&1 | head

so I can see only the first few errors.

I always have trouble remembering this, and I constantly have to go look it up, and it is mainly because I don't fully understand the syntax of this particular trick. Can someone break this up and explain character by character what "2>&1" means?

+9  A: 

The numbers refer to the file descriptors (fd). Zero is stdin, one is stdout, and two is stderr. "2>&1" redirects fd 2 to 1. This works for any number of file descriptors if the program uses them.

You can look at /usr/include/unistd.h if you forget them:

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */

That said I have written C tools that use non-standard file descriptors for custom logging so you don't see it unless you redirect it to a file or something.

Colin Burnett
+9  A: 
echo test > afile.txt

..redirects stdout to afile.txt. This is the same as doing..

echo test 1> afile.txt

To redirect stderr, you do..

echo test 2> afile.txt

>& is the syntax to redirect a stream to another file descriptor - 0 is stdin. 1 is stdout. 2 is stderr.

You can redirect stdin to stderr by doing..

echo test 1>&2 # or echo test >&2

..or vice versa:

echo test 2>&1

So, in short.. 2> redirects stderr to an (unspecified) file, appending &1 redirects stderr to stdout

dbr
+16  A: 
  • 2 is the default file descriptor for stderr.
  • 1 is the default file descriptor for stdout.
  • >& is shell syntax for "fold a file descriptor into another"
Bill Karwin
Technically correct, but this isn't really any help to someone who doesn't already understand output redirection very well.
David Zaslavsky
The OP does understand output redirection. He just asked for a breakdown of the syntax.
Bill Karwin
The OP is not the only one that will be asking this question and looking for an answer (at least, that's the stated purpose of SO).
Adriano Varoli Piazza
+25  A: 

1 is stdout. 2 is stderr.

Here is one way to remember this construct (altough it is not entirely accurate): at first, 2>1 may look like a good way to redirect stderr to stdout. However, it will actually be interpreted as "redirect stderr to a file named 1". & indicates that what follows is a file descriptor and not a filename. So the construct becomes: 2>&1.

Ayman Hourieh
Svante
Indeed. Fixed now. Thanks!
Ayman Hourieh
+3  A: 

To answer your question: It takes any error output (normally sent to stderr) and writes it to standard output (stdout).

This is helpful with, for example 'more' when you need paging for all output. Some programs like printing usage information into stderr.

To help you remember

  • 1 = standard output (where programs print normal output)
  • 2 = standard error (where programs print errors)

"2>&1" simply points everything sent to stderr, to stdout instead.

I also recommend reading this post on error redirecting where this subject is covered in full detail.

Andrioid
+2  A: 

That construct sends the standard error stream (stderr) to the current location of standard output (stdout) - this currency issue appears to have been neglected by the other answers.

You can redirect any output handle to another by using this method but it's most often used to channel stdout and stderr streams into a single stream for processing.

Some examples are:

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

Note that that last one will not direct stderr to outfile2 - it redirects it to what stdout was when the argument was encountered (outfile1) and then redirects stdout to outfile2.

This allows some pretty sophisticated trickery.

paxdiablo
Although that last example would be much clearer as: foo >outfile2 2>outfile1
Michael Cramer
Clearer, yes, but that wouldn't show the "positional" nature of redirection. The example is contrived since it's not usually useful to do this in a single line - the method becomes really useful when different parties are responsible for the different parts of the redirection. For example, when a script does one bit of redirection and you run it with another bit.
paxdiablo
A: 

I used to forget what order to put the characters in, since I didn't know what they were doing. (And I'm still not 100%!) The way I remember this construct is with the mnemonic "two is greater than one".

Bubba Grump