48

I know what

  program > /dev/null 2>&1 

does. It redirects the output to /dev/null and 2>&1 means to redirect the error output in the same place where the output is sent.

My problem is I always have to google it because I never remember it.

So, I try &2>1, 1>2&, 1>&2... I try every combination until I google it...

What's the trick to remember it easily?

RegDwight
  • 111
Luc M
  • 4,095
  • 5
  • 30
  • 29
  • I have the same issue, so I do it the "long" way - redirect both program 1> /dev/null 2>/dev/null. Some times though you do need to mix the stdout and stderr together to see what is really going on - like the output from a complex compile process being redirected to a file. In that case, I end up googling it – ivanivan Jul 01 '18 at 14:37
  • Great description here: https://unix.stackexchange.com/a/99264/114401. – Gabriel Staples Jan 24 '21 at 00:00

9 Answers9

23

Output is better than error so it comes first (1 vs 2).

> is shorthand for 'goes to'. On the left is what I want to send and on the right is where I want to send it. Since 'where' is (almost) always a file, something like

program > /dev/null 2>1

would redirect to a file named 1. Thus, the ampersand (&) modifies the file to file descriptor.

Unfortunately, I haven't come across nor developed my own mnemonic, but when I was first learning *nix, I found this logical way to work well. After a few run-throughs, it becomes second nature.

gvkv
  • 2,738
  • 1
    Your first sentence doesn't make sense to me. stdout is file descriptor 1, stderr is 2. So, "error" comes before "output". – Warren Young Aug 19 '10 at 13:15
  • That sentence is a mnemonic to remember which file descriptor stdout and stderr refer. – gvkv Aug 19 '10 at 13:53
  • 1
    Okay, but it still seems confusing, since the original question is about trying to remember the order of the characters in the "2>&1" incantation. – Warren Young Aug 19 '10 at 13:56
11

One trick is just to remember that 1 = standard output, 2 = standard error. So:

2>&1 = standard error stream goes into standard output stream.
1>&2 = vice versa.

If you have ever programmed in a C-like language, it's easy to remember the ampersand (&). I choose to think of it as referring to the "address of" existing file descriptor, so that you don't change the file itself or create a new one.

Kevin
  • 40,767
7

Seeing the & as a knot might help : think about what you want to do as taking the output of 2, so 2>, and tying it together with 1, so 2>&1

  • 2
    I just memorized the phrase "two out and one". Whether your mnemonic is a phrase or a knot, having one will really help. – Tim Kennedy Oct 08 '11 at 15:56
5

Let us consider these three options:

program  2>1
program  2>1& 
program  2>&1

The first sends stderr to a file names "1": after all, bash expects to redirect to a file.

The second also redirects to the same file but runs program in the background: that is what a trailing & is supposed to mean.

That leaves the third possibility as the only one that makes sense in the bash universe for redirecting to a file handle.

How to remember which is which among 0, 1, 2? Think about running a computer from the console. First, you have to type something (0=stdin). Then, you see output (1=stdout). Lastly and only if something goes wrong, you see stderr (2).

John1024
  • 74,655
5

Actually, it depends on what shell you're using. Bash is usually very forgiving and you can just do:

program &> file
Kevin Cantu
  • 3,794
1

In regards to the bash shell I find the best way to remember is by understanding what is happening.
If all you want to do is remember how to get the command correct, you might try

program > /results 2> /results

That's nice and obvious whats going on and easy to remember. i.e.

  • 1 STDOUT is going to /results
  • 2 STDERR is also going directly to /results

the problem is this doesn't work as you would expect. consider the following:

file: /tmp/poem.txt

the quick brown fox jumped over the lazy dog

and the run the command

grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results

then

$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
 lazy dog

what happened here?
My understanding is bash setup the redirection pointing the STDERR directly to the file /tmp/results and because of the nature of > which does 2 things

  1. normally create a new file - in this case the opportunity has passed as bash has moved past this routine at the time the output is generated.
  2. insert straight into the beginning of the file. and not append like >> does.

So in this case STDERR, inserts directly into the beginning of /tmp/results overriding the output of STDOUT.
Note: if you used >> to append you could probably get away with this syntax.
However to fix the problem you need - not to redirect STDERR - to the file directly, but rather to merge STDERR's output into the STDOUT stream, so you don't get a collision.
Using the operator 2>&1 operator achieves this

grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1

The & enables bash to distinguish from a file named 1 and the 1 file descriptor.
To me the statement 2>&1 itself explains exactly what is happening - STDERR is being redirected at STDOUT itself - and only ends up in /tmp/results because thats where STDOUT is pointed (almost as a side effect).
As opposed to what alot of guides claim, which is that 2>&1 sends STDERR to where ever STDOUT is pointed. If that were true - you would still have the overwriting problem.

For more information see - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection

1

Read 2>&1 as redirect stderr(2), to where stdout(1) is currently going.

As we read (and it is processed) left to right. The correct reading of >file 2>&1 is direct stdout to file, then direct stderr to the same place that stdout is now going.

1

Draw it in your wallpaper.

Now, seriously, this and other basic stuff I kept forgetting, so I added a quick tips menu to an app I developed and that I use daily. You might want to give it a try or use something like gnote to keep a note.

RegDwight
  • 111
0

FWIW, to offer more of a "teach a man to fish" answer since the other answers you got here say what the 2>&1 means, you could always use https://explainshell.com when you don't quite understand what's going on. It's not perfect, but does give a pretty good starting point when dissecting a bash/shell command.

e.g. For your question: https://explainshell.com/explain?cmd=program+%3E+%2Fdev%2Fnull+2%3E%261

yuyu5
  • 101
  • 1
    Quoting page "How do I write a good answer" Links to external resources are encouraged, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the external resource is unreachable or goes permanently offline. – Luc M Oct 12 '20 at 21:15