Reputation: 911
From the bash man pages, under the section "Redirection":
Redirecting Standard Output and Standard Error
This construct allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) to be redirected to the file whose name is the expansion of word.
There are two formats for redirecting standard output and standard error:
&>word
and
>&word
Of the two forms, the first is preferred.
That made me wonder, why is the first preferred? I see that &>>
works, but >>&
does not, so the preference makes sense. So why does >>&
not work? Is it ambiguous?
Here's what I'm running
$ bash --version
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
Upvotes: 1
Views: 68
Reputation: 295272
&>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.
Upvotes: 3