What does "2>&1" do in command line?

60

39

I know that the > sign is used for output redirection in the command line, but I'm having trouble finding something that explains the use of 2>&1 in the command line. For example:

curl http://www.google.com > /dev/null 2>&1 &

Matt Huggins

Posted 2009-11-16T23:15:18.450

Reputation: 989

Answers

79

The 1 denotes standard output (stdout). The 2 denotes standard error (stderr).

So 2>&1 says to send standard error to where ever standard output is being redirected as well. Which since it's being sent to /dev/null is akin to ignoring any output at all.

Chealion

Posted 2009-11-16T23:15:18.450

Reputation: 22 932

is 2>&1 > /dev/null the same as > /dev/null 2>&1? It seems more natural to me... – edelans – 2014-09-10T16:50:01.410

1

@edelans No, order matters, so 2>&1 will redirect stderr to the current value of stdout, then >/dev/null changes stdout. See cmd-21-log-vs-cmd-log-21

– Nigel Touch – 2015-04-29T16:13:43.080

@Nigel thanks, it's crystal clear now, +1 for linking to such a clean answer. – edelans – 2015-04-29T16:44:25.263

3Is there a reason that an ampersand appears before the 1, but not before the 2? I thought the & was a reserved character for running a job in the background, but I guess that's only if the ampersand appears as a long character at the end of a command...? – Matt Huggins – 2009-11-16T23:24:02.957

9Because 0 (stdin), 1 (stdout) and 2 (stderr) are actually file descriptors the shell requires an ampersand put in front of them for redirection. It duplicates the file descriptor in this case effectively merging the two streams of information together. – Chealion – 2009-11-16T23:36:27.113

13Think of it this way: if you just had "1" with no ampersand, the shell would create a file named "1" and redirect stderr output to it. – CarlF – 2009-11-17T06:05:56.923

1Okay, would this alone be valid then? curl http://www.google.com 2>/dev/null How does the command line know that the "2" here is intended to mean stderr and isn't actually the second parameter that I'm passing to the curl command? – Matt Huggins – 2009-11-17T18:21:11.870

1@Matt Huggins: Yes. That would send all output from stderr straight to /dev/null instead. You can see it in practice by trying curl, curl 1>/dev/null and curl 2>/dev/null just to see the output change. Again the ampersand is only needed for the file descriptor being redirected to. – Chealion – 2009-11-18T00:34:28.820

@MattHuggins What does the & in the end do here, after 1?? – Richa Agrawal – 2014-02-24T06:52:24.060

@infantDev: The & at the very end of the command in the question means the command runs in the background. – Chealion – 2014-02-25T18:36:24.753

24

tl;dr

Fetch http://www.google.com in the background and discard both the stdout and stderr.

curl http://www.google.com > /dev/null 2>&1 &

is the same as

curl http://www.google.com > /dev/null 2>/dev/null &

Basics

0, 1 and 2 represent the standard file descriptors in POSIX operating systems. A file descriptor is a system reference to (basically) a file or socket.

Creating a new file descriptor in C can look something like this:

fd = open("data.dat", O_RDONLY)

Most Unix system commands take some input and output the result to the terminal. curl will fetch whatever is at the specified url (google dot com) and display the result to stdout.

curl result

Redirection

Like you said < and > are used to redirect the output from a command to somewhere else, like a file.

For example, in ls > myfiles.txt, ls gets the current directory's contents and > redirects its output to myfiles.txt (if the file doesn't exist it is created, otherwise overwritten, but you can use >> instead of > to append to the file instead). If you run the command above, you will notice nothing is displayed to the terminal. That usually means success in Unix systems. To check this cat myfiles.txt to display the file contents to the screen.

> /dev/null 2>&1

The first part > /dev/null redirects the stdout, that is curl's output to /dev/null (more on this ahead) and 2>&1 redirects the stderr to the stdout (which was just redirected to /dev/null so everything will be sent to /dev/null).

The left side of 2>&1 tells you what will be redirected, and the right side tells you where to. The & is used on the right side to distinguish stdout (1) or stderr (2) from files named 1 or 2. So, 2>1 would end up creating a new file (if it doesn't exist already) named 1 and dump the stderr result in there.

/dev/null

/dev/null is an empty file, a mechanism used to discard everything written to it. So, curl http://www.google.com > /dev/null is effectively suppressing curl's output.

> /dev/null

But why is there some stuff still displayed on the terminal?. This is not curl's regular output, but data sent to the stderr, used here for displaying progress and diagnostic information and not just errors.

curl http://www.google.com > /dev/null 2>&1 ignores both curl's output and curls progress information. The result is nothing is displayed on the terminal.

Finally

The & at the end is how you tell the shell to run the command as a job in the background. This causes the prompt to return immediately while the command is run asynchronously behind the scenes. To see the current jobs type jobs in your terminal. Note this is different from the processes running in your system. To see those type top in the terminal.

References

Jorge Bucaran

Posted 2009-11-16T23:15:18.450

Reputation: 411

1This is one of the best answers on the entire website from a layout perspective, well done! – OmarOthman – 2016-04-04T14:32:43.583

One thing I'm not getting is why you would want to send everything to /dev/null ? Don't you want the results of the curl at least somewhere useful? – skube – 2016-11-15T23:40:39.957

@skube Right. In this case it's not clear to me why the user wants to discard both stdout and stderr. OP probably just wanted to understand what the syntax meant. – Jorge Bucaran – 2016-11-16T02:17:31.840

5

2 refers to STDERR. 2>&1 will send STDERR to the same location as 1 (STDOUT).

John T

Posted 2009-11-16T23:15:18.450

Reputation: 149 037

0

My understand as follow:

If you only want to read the Output and Error information of the command on the screen, then just write: curl http://www.google.com

And some times you want to save the Output information to a file instead of terminal screen for later review, then you can write: curl http://www.google.com > logfile

But in this way, the StdErr information will be omitted, since > only redirect the StdOut to logfile.

So if you care about the error information of the command once it fail to execute, then you need to combine StdOut with StdErr by using 2>&1 (which means fold StdErr into StdOut), so the following command line can be written: curl http://www.google.com > logfile 2>&1

YaOzI

Posted 2009-11-16T23:15:18.450

Reputation: 459