&>dest
is unambiguous, whereas >&dest
looks like fdup()
syntax ...and can be construed as fdup
syntax when you have a numeric filename.
Bash, since 4.1 or later, allows the destination of a fdup
operation to be parameterized -- thus, not just 2>&1
, but also 2>&$stderr_fd
. Putting the &
after the >
puts us into the namespace of syntax used for fdup()
operations; keeping it beforehand is unambiguous.
Example: I want to redirect the stdout and stderr of the command cmd
into my file. If my file's name is 0
, >&
causes issues.
cmd >& 0
becomes cmd 1>&0
. That is, redirect stdout to fd#0.
cmd &> 0
becomes cmd > 0 2>&1
. That is, redirect stdout to the file named 0
, then redirect stderr to fd#1.
[n]>&word
is POSIX-standardized; &>word
is not found anywhere in the POSIX standard.
The only forms for duplicating existing file descriptors defined by the POSIX standard are [n]<&word
and [n]>&word
. In the grammar, these are given the token names GREATAND
and LESSAND
.
There are no POSIX-defined tokens for &>
or &<
– they are merely syntactic sugar for the commonly used operation of "I don't want to see anything on my screen", or "send stdout and stderr to a file".
This is useful, because cmd 2>&1 > myFile
- surprisingly to those new to bash - doesn't work as intended for the "clean screen" goal, whereas cmd > myFile 2>&1
, does.
So.. why does &>>
work when >>&
does not? Because whoever wrote &>>
didn't feel the need to create an ambiguity, and consciously chose to not allow >>&
.
fdup()
synonyms with >>
would not add value.
To explain a bit more about why [n]>&word
synonyms are pointless -- keep in mind that the difference between >bar
and >>bar
is the presence of the O_APPEND
flag and absence of O_TRUNC
in the flags
argument to open()
. However, when you're providing a file descriptor number -- and thus performing an fdup()
from an old FD number to a new one -- the file is already open; the flags thus cannot be changed. Even the direction -- >
vs <
-- is purely informational to the reader.
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
, neither&>>
nor>>&
work.