16

On this SO thread and a few other threads I have seen the following commands for redirecting stdout and stderr to a file.

Are they all equivalent? Is there any difference between them?

command1 >> logfile 2>&1
command &> logfile
command >& logfile

2 Answers2

10

Since you have tagged zsh, let me tell you that all the 3 redirections works exactly the same way. As you might have read in both the duplicate posts (the one in the comment and the one in your post), they all redirect stderr to stdout which inturn is redirected to the file 'logfile' (ie, the logfile will contain both the output and errors).

But their behaviour changes a LOT depending on the shell you are in.

All the three styles of redirections works well in the same way in bash and zsh

But:

Only >& works in csh or tcsh

[soum@server ~]$  ./test.sh > logfile 2>&1
Ambiguous output redirect.
[soum@server ~]$ ./test.sh &> logfile
Invalid null command.
[soum@server ~]$ ./test.sh >& logfile
[soum@server ~]$ echo $SHELL
/bin/tcsh
[soum@server ~]$

In ksh only 2>&1 works.

$ ./test.sh >& logfile
-ksh: logfile: bad file unit number
$ ./test.sh &> logfile
[1]     23039
$ 1  2  3  4  5  6  logfile  test.sh
ls: cannot access ttr: No such file or directory

[1] +  Done(2)                 ./test.sh &> logfile

I hate ksh. While >& just gave an error, the &> backgrounded a part of the command and emptied the logfile (if non-empty).

Sreeraj
  • 5,062
1

&> and >& semi-equivalence (clobber)

The zsh manual Redirections section says that:

  • &>
  • >&

are equivalent.

Both will clobber the file - truncate it file to 0 bytes before writing to it, just like > file would do in the STDIN-only case.

However, the bash manual Redirections section adds that:

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

>word 2>&1

When using the second form, word may not expand to a number or -. If it does, other redirection operators apply (see Duplicating File Descriptors below) for compatibility reasons.

So, whilst you tagged zsh, it's probably good practice to get finger memory in the first form should one ever write a bash script.

>> logfile 2>&1 and &>> equivalence (append)

Here, logfile is not overwritten, but opened for writing at the end of the file, ie append mode (O_APPEND).

The equivalent in both {ba,z}sh is:

command1 &>> logfile

In bash:

The format for appending standard output and standard error is:

&>>word

This is semantically equivalent to

>>word 2>&1

(see Duplicating File Descriptors below).

(Note: the clobber usage of &> over >& in the section above is again recommended given there is only one way for appending in bash.)

zsh allows both &>> and >>& forms.

Tom Hale
  • 30,455