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?
2 is the console standard error.
1 is the console standard output.
This is the standard Unix, and Windows also follows the POSIX.
E.g. when you run
the standard error is redirected to standard output, so you can see both outputs together:
After execution, you can see all the output, including errors, in the debug.log.
Then standard output goes to out.log, and standard error to err.log.
I suggest you to try to understand these.
From a programmer's point of view, it means precisely this:
See the man page.
Understanding that
2>&1
is a copy also explains why ...... is not the same as ...
The first will send both streams to
file
, whereas the second will send errors tostdout
, and ordinary output intofile
.The numbers refer to the file descriptors (fd).
stdin
stdout
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: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.
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
"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.
People, always remember paxdiablo's hint about the current location of the redirection target... It is important.
My personal mnemonic for the
2>&1
operator is this:&
as meaning'and'
or'add'
(the character is an ampers-and, isn't it?)2
(stderr) to where1
(stdout) already/currently is and add both streams'.The same mnemonic works for the other frequently used redirection too,
1>&2
:&
meaningand
oradd
... (you get the idea about the ampersand, yes?)1
(stdout) to where2
(stderr) already/currently is and add both streams'.And always remember: you have to read chains of redirections 'from the end', from right to left (not from left to right).
I found this brilliant post on redirection: All about redirections
Redirect both standard output and standard error to a file
This one-liner uses the
&>
operator to redirect both output streams - stdout and stderr - from command to file. This is Bash's shortcut for quickly redirecting both streams to the same destination.Here is how the file descriptor table looks like after Bash has redirected both streams:
As you can see, both stdout and stderr now point to
file
. So anything written to stdout and stderr gets written tofile
.There are several ways to redirect both streams to the same destination. You can redirect each stream one after another:
This is a much more common way to redirect both streams to a file. First stdout is redirected to file, and then stderr is duplicated to be the same as stdout. So both streams end up pointing to
file
.When Bash sees several redirections it processes them from left to right. Let's go through the steps and see how that happens. Before running any commands, Bash's file descriptor table looks like this:
Now Bash processes the first redirection >file. We've seen this before and it makes stdout point to file:
Next Bash sees the second redirection 2>&1. We haven't seen this redirection before. This one duplicates file descriptor 2 to be a copy of file descriptor 1 and we get:
Both streams have been redirected to file.
However be careful here! Writing
is not the same as writing:
The order of redirects matters in Bash! This command redirects only the standard output to the file. The stderr will still print to the terminal. To understand why that happens, let's go through the steps again. So before running the command, the file descriptor table looks like this:
Now Bash processes redirections left to right. It first sees 2>&1 so it duplicates stderr to stdout. The file descriptor table becomes:
Now Bash sees the second redirect,
>file
, and it redirects stdout to file:Do you see what happens here? Stdout now points to file, but the stderr still points to the terminal! Everything that gets written to stderr still gets printed out to the screen! So be very, very careful with the order of redirects!
Also note that in Bash, writing
is exactly the same as: