0

I actually have 2 questions:

  1. What does >& mean in a shell script as in /usr/bin/x_app >& /tmp/blog.txt? Shouldn't a number follows & to make it a stdout/err thing?

  2. As far as I know that > is overwriting and >> is appending, so 2>&1 should just replace stdout with stderr, but instead, it means putting stdout and stderr together. Why don't we use >>? I mean I know "appending" does not mean "putting them together" either but it's closer to it than "overwriting", right?

  • For the 2nd question: 2>&1 means just dup2(1, 2) and is absolutely the same as 2<&1. After it, the 2 and 1 fds can be used interchangeably. Don't try to read to much into; the only difference between <& and >& is what fd is the default on the left side when not specified (0 vs 1). – Uncle Billy Jan 17 at 22:39
4

>& file is a csh operator (from the late 70s) to redirect both stdout and stderr to file. The Bourne shell (also from the late 70s) equivalent is > file 2>&1, or 2> file >&1, that is redirect fd 1 to file and then fd 2 to the same open file description or vice versa.

zsh and bash are two shells (from the late 80s, early 90s) that took features from both the Korn¹ shell (and by extension the Bourne shell) and csh, and support that >& csh operator in addition to the [i]>&j Bourne/Korn operator.

Those two conflicts though.

cmd >& "$var"

Will end up doing the Bourne/Korn redirection if $var contains a number and the csh one otherwise.

In practice, it's better to avoid that csh operator and use the Bourne syntax instead (cmd > "$var2" 2>&1) in those shells to avoid surprises.

Note that initially, bash didn't support csh's >& but had &> instead for the same feature. That also conflicted with Bourne syntax. In the Bourne shell, cmd &> file is cmd and > file run in parallel. zsh also added support for &> latter for compatibility with bash.

You'll find yet different syntax in different shells. In rc (late 80s) and derivatives (es, akanga), Bourne's 2>&1 is written >[2=1] (and it makes it easier to specify which fds are to be at each end of pipes: cmd1 |[3=4] cmd2 (connecting fd 3 of cmd1 to fd 4 of cmd2 via a pipe) which in Bourne syntax, you'd need to write { cmd1 3>&1 >&5 5>&- | 4<&0 <&6 6<&- cmd2; } 5>&1 6<&0).

The fish shell (mid 2000s) has different variations in I/O redirection syntax from the Bourne shell's.


¹ The Korn shell (from the early 80s) was based on the Bourne shell but also borrowed features from csh like aliases, tilde expansion and brace expansion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.