What does 2>&1 mean?
Tags: unix, redirection, stdout, stderr
Published: 2020-04-17 15:25:20

---
title: What does 2>&1 mean?
published: true
description: What does 2>&1 mean
tags: unix, redirection, stdout, stderr
---

If you have been shell scripting for a while, you may have seen `1>&2` or `2>&1` idioms. Ex:

```
SOME_COMMAND > /dev/null 2>&1
```
This article will explain what that strange-looking `2>&1` means.

**TL;DR:**
*`2>&1` means redirect the stderr (`>2`) to where stdout is being redirected to (`&1`)*.

Before we start, I want to go over a basic concept of file descriptors. There are 3 file descriptors in UNIX and each is associated with a number:


| Name           | Short Name    | File Descriptor Number| Description          |
| --------------:|:-------------:| ---------------------:| ---------------------:
| Standard In    | `stdin`       | 0                     | Keyboard Input       |
| Standard Out   | `stdout`      | 1                     | Console Output       |
| Standard Error | `stderr`      | 2                     | Console Error Output |


We won't cover `stdin` in this article, but we will talk about `stdout` and `stderr`. Let's go!

# `stdout`

When you execute a command, for example: `ls`. You will see the result of your command displayed on your screen. In this case, I see:

```
> ls
README.md      components       src       
```

Let's do one more: 

```
> echo "hello"
hello
```

These are examples of `stdout`. They all have file descriptor value of 1. If you want to learn more about file descriptors, check out resources at the end of this post.

## `stdout` redirection

You can redirect your `stdout` with `>`.

```
> echo "Hello stdout" > result.txt
> cat result.txt
Hello stdout
```

We no longer see "Hello stdout" after running `echo`. This is because instead of `"Hello stdout"` being displayed to console, it gets redirected to `result.txt`. The file `result.txt` contains our `echo` output: `"Hello stdout"`.

Let's try one more:
```
> ls > result.txt
> cat result.txt
README.md
component
src 
```
This time you see the content of `ls` inside `result.txt`.

My point is, **everything you see on your screen** *(that is not error)* - every `stdout` - can be redirected with `>`.

By the way, `>` is actually a shorthand for `1>`. If you do:
```
> echo "Hello redirection" 1> result.txt
> cat result.txt
Hello redirection
```
You get the same functionality using `1>` as with `>`. Keep this in mind.

# `stderr`

Sometimes we may encounter error running a command:

```
> cat filedoesntexist.txt
cat: filedoesntexist.txt: No such file or directory

> ls idontexist
ls: idontexist: No such file or directory
```

Let's compare running two different commands. Replace `something_that_exists` below with an actual file in your current directory. 

```
> cat something_that_exists
> cat something_that_doesnt_exist
```

Although they each return some sort of output, your computer doesn't interpret these two outputs the same way. `cat something_that_exists` has file descriptor of 1 and `cat something_that_doesnt_exist` has file descriptor of 2.

## `stderr` redirection
Let me show you how they're different. If we try to redirect a bad `cat` (😺 pun not intended):

```
> cat filedoesntexist > result.txt
cat: filedoesntexist: No such file or directory
> cat result.txt
```
You see `cat: filedoesntexist: No such file or directory` error displayed on your console and `result.txt` is empty. Our redirection redirects nothing.

This is because when we perform `cat filedoesntexist`, we get a `stderr` and not `stdout`. When we tried to redirect `stdout` to result.txt with `> result.txt`, there is no `stdout` to be redirected. To redirect `stderr`, we need to use `stderr` redirect, not `stdout` redirect. To redirect `stderr`, we use `2>`.

```
> cat filedoesntexist 2> result.txt
> cat result.txt
cat: filedoesntexist: No such file or directory
```

This looks better. We no longer sees the error output when running `cat filedoesntexist` **and** our `result.txt` contains `cat: filedoesntexist: No such file or directory` error string. We have successfully redirected our bad `cat` 😸!

So we learned that there are at least 2 redirections: `>` and `2>`. The former redirects normal outputs, the latter redirects error outputs.

To reinforce our knowledge, what do you think will happen if we do `echo` and use `2>` redirection? Don't read further. Spend some time to think about this. When you're ready, read on.

.
.
.
.
.
.
.
.
.
.


```
> echo "Hello Cat" 2> result.txt
Hello Cat
> cat result.txt
```

We see `Hello Cat` being echoed to our console and `result.txt` is blank, because we are redirecting `stderr` from our `echo`. Since our `echo` doesn't return any error, nothing gets redirected to `result.txt`.

# `stdout`, `stderr`, and `2>&1`

Let's do one last example. 

```
> ls myDir > result.txt 2> result.txt
```
This will redirect `stdout` and `stderr` from running `ls myDir` to `result.txt`. This way, if `myDir` exists, it will redirect the output to `result.txt` and if `myDir` doesn't exist, it will redirect the error message to `result.txt`. User will not see any output whether the command works or not. It's a win-win.

This feels a bit too long, doesn't it? Luckily we can shorten it:
```
> ls myDir > result.txt 2>&1
```
Hey, look at that! Our `2>&1` idiom. It means *redirect any stderr (`2>`) to the same place we are redirecting stdout (`&1`)*.

That's right! `ls myDir > result.txt 2>&1` is the same as `ls myDir > result.txt 2> result.txt`. Think about this. Internalize it.

You can mix file descriptors, for example, what do you think this does?

```
> ls myDir 2> result.txt 1>&2
```

You might've guessed it now: `1>&2` means "redirect the `stdout` to where `stderr` is being redirected to".


So what do people use `2>&1` for? I have seen people running the command we see above (ex: [Crontab quick reference (disable email)](https://www.adminschoice.com/crontab-quick-reference)):

```
> CMD > /dev/null 2>&1
```

The script above redirects the output and error messages from whatever `CMD` you're running to `/dev/null` *(if you're wondering what is `/dev/null`, it is a special file that discards everything written to it. I think of it like a black hole/ paper shredder)*.

This is a good place to stop.

I hope that makes sense so far. If not, I suggest either reread it or read some from resources below. Take your time understanding this, especially if it is new. It took me a while to understand it.

Thank you so much for reading! Appreciate it. Now go write some cool scripts with this!


# Resources

- [File Descriptor (Definitions)](https://www.computerhope.com/jargon/f/file-descriptor.htm)
- [File Desciptor - General Unix and Advanced C](https://www.bottomupcs.com/file_descriptors.xhtml)
- [What does “2>&1” do in command line?
](https://superuser.com/questions/71428/what-does-21-do-in-command-line)
- [Understanding Shell Script's idiom: 2>&1](https://www.brianstorti.com/understanding-shell-script-idiom-redirect/)
- [What does '>/dev/null 2>&1' mean in this article of crontab basics?](https://unix.stackexchange.com/questions/163352/what-does-dev-null-21-mean-in-this-article-of-crontab-basics)
- [What does “/dev/null” mean at the end of shell commands](https://stackoverflow.com/questions/13408619/what-does-dev-null-mean-at-the-end-of-shell-commands)