tags:

views:

780

answers:

7

There seem to be two bash idioms for redirecting STDOUT and STDERR to a file:

fooscript &> foo

... and ...

fooscript > foo 2>&1

What's the difference? It seems to me that the first one is just a shortcut for the second one, but my coworker contends that the second one will produce no output even if there's an error with the initial redirect, whereas the first one will spit redirect errors to STDOUT.

EDIT: Okay... it seems like people are not understanding what I am asking, so I will try to clarify:

Can anyone give me an example where the two specific lines lines written above will yield different behavior?

+1  A: 
&> foo # Will take all and redirect all output to foo.

2>&1 # will redirect stderr to stdout.
J.J.
Max
In the first all output goes to foo. In the second fooscript sends stdout to foo and then foo sends sends stderr to stdout, and it prints where ever stdout is pointed to. (usually console)
J.J.
Yes, but what's the difference between those two things? Is there one? Can you give an example of a situation where they would yield different behavior?
Max
A: 

2>&1 might be useful for cases where you aren't redirecting stdout to somewhere else, but rather you just want stderr to be sent to the same place (such as the console) as stdout (perhaps if the command you are running is already sending stderr somewhere else other than the console).

matt b
+1  A: 

2>&1 depends on the order in which it is specified on the command line. Where &> sends both stdout and stderr to wherever, 2>&1 sends stderr to where stdout is currently going at that point in the command line. Thus:

command > file 2>&1

is different than:

command 2>&1 > file

where the former is redirecting both stdout and stderr to file, the latter redirects stderr to where stdout is going before it is redirected to the file (in this case, probably the terminal.) This is useful if you wanted to do something like:

command 2>&1 > file | less

Where you want to use less to page through the output of stderr and store the output of stdout to a file.

Steve Baker
+2  A: 
ephemient
+3  A: 

The main reason to use 2>&1, in my experience, is when you want to append all output to a file rather than overwrite the file. With &> syntax, you can't append. So with 2>&1, you can write something like program >> alloutput.log 2>&1 and get stdout and stderr output appended to the log file.

KernelM
+7  A: 

From the bash manual:

There are two formats for redirecting standard output and standard error:

&>word

and

>&word

Of the two forms, the first is preferred. This is semantically equivalent to

 >word 2>&1

The phrase "semantically equivalent" should settle the issue with your coworker.

Bruno De Fraine
A: 

The situation where the two lines have different behavior is when your script is not running in bash but some simpler shell in the sh family, e.g. dash (which I believe is used as /bin/sh in some Linux distros because it is more lightweight than bash). In that case,

fooscript &> foo

is interpreted as two commands: the first one runs fooscript in the background, and the second one truncates the file foo. The command

fooscript > foo 2>&1

runs fooscript in the foreground and redirects its output and standard error to the file foo. In bash I think the lines will always do the same thing.

Jouni K. Seppänen
ephemient
Jouni K. Seppänen