">&"是什么意思?

122

我对这个表达式有点困惑:

gcc -c -g program.c >& compiler.txt

我知道 &>filename 可以将标准输出和标准错误都重定向到文件 filename。但在这种情况下,和号是大于号之后的。它看起来像是这个形式:M>&N,其中 MN 是文件描述符。

在上面的片段中,M=1N='compiler.txt' 吗?这与以下内容有什么不同:

gcc -c -g program.c > compiler.txt     (ampersand removed)

我的理解是每个打开的文件都与大于2的文件描述符相关联。这正确吗?

如果是这样,那么文件名是否可以与其文件描述符交换作为重定向的目标?

3个回答

137

这与 &> 相同。来自 Bash 手册:

重定向标准输出和标准错误 该结构允许将标准输出(文件描述符1)和标准错误输出(文件描述符2)同时重定向到单词扩展后的文件名所表示的文件中。

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 equiva-
lent to

       >word 2>&1

13
我感觉很傻。我花了很多时间阅读其他资料,而它就在man页面上。 - contrapositive
3
>&是csh和tcsh用于重定向标准输出和标准错误输出的语法。这可能就是为什么bash也能接受它的原因。 - Keith Thompson
4
这是否意味着 &>word>word 2>&1 在语义上是等价的?“这”所指的先行词对我来说不太清楚。 - geneorama
13
"@geneorama &>word>word 2>&1>&word完全相同。" - jordanm
1
现在我意识到之前我根据别处的阅读理解错了。> 只会重定向标准输出,而不会重定向错误输出。(也许我应该将未来的评论重定向到 /dev/null - geneorama
显示剩余6条评论

27

&> vs >&: 推荐使用 &> (截断)

关于:

  • &>
  • >&

两种方式都会截断文件-在仅有STDIN的情况下,就像> file一样。

然而bash手册中的重定向部分补充说:

在这两种形式中,第一种被推荐。这在语义上等同于

>word 2>&1

当使用第二种形式时,word可能不会扩展为数字或-。如果扩展了,出于兼容性原因,将应用其他重定向运算符(请参见下面的复制文件描述符)。

(注意:zsh中两者是等效的。)

最好练习使用第一种(&>)形式,因为:

使用&>>作为>>&不受bash支持(追加)

只有一种追加形式:

追加标准输出和标准错误的格式为:

&>>word

这在语义上等同于

>>word 2>&1
(见下面的“复制文件描述符”)。
注意: - 建议在上面的部分中再次使用&>而不是>&,因为在bash中只有一种追加方式。 - zsh允许使用&>>>>&两种形式。

那么 & 是一个特殊字符,会被 shell 解释器转换为 1 和 2 吗? - Fakher Mokadem
@FakherMokadem 不是的,请看手册 - Tom Hale

3
略微偏题,但这就是为什么我始终坚持使用长格式,如>/dev/null 2>&1。 对于那些在类似cron的事情中倒过来做的人来说,这已经够令人困惑了,不需要再加上 >&, &>, >>&, &>>, ...。 我经常需要在crontab -l中添加注释,提醒人们"2>&1 > /dev/null"不是最佳实践。
只要记住任何“最终目标”都应该首先给出,那么在任何Unix或类Unix系统上,使用任何Bourne-like shell,无论是追加还是其他方式,语法应该是相同的。 此外,由于&>实际上是Bash-ism(可能起源于csh?不记得了,但它也不是POSIX),因此它并不总是受到商业UNIX系统的支持。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接