“&> foo”和“> foo 2>& 1”之间有什么区别?

时间:2008-10-09 17:01:48

标签: bash

似乎有两个bash惯用法将STDOUT和STDERR重定向到一个文件:

fooscript &> foo

......和......

fooscript > foo 2>&1

有什么区别?在我看来,第一个只是第二个的快捷方式,但我的同事争辩说,即使初始重定向出错,第二个也不会产生输出,而第一个会将重定向错误吐出到STDOUT。

编辑:好的......似乎人们不理解我的要求,所以我会尽力澄清:

有人能举例说明上面写的两条特定行行会产生不同的行为吗?

8 个答案:

答案 0 :(得分:8)

来自bash manual

  

有两种格式可以重定向标准输出和标准错误:

&>word
     

>&word
     

在这两种形式中,第一种是首选。这在语义上等同于

 >word 2>&1

短语“语义上相同”应与您的同事解决问题。

答案 1 :(得分:6)

两行具有不同行为的情况是当你的脚本没有在bash中运行但是在sh族中有一些更简单的shell时,例如dash(我认为它在某些Linux发行版中用作/ bin / sh,因为它比bash更轻量级)。在那种情况下,

fooscript &> foo

被解释为两个命令:第一个命令在后台运行fooscript,第二个命令截断文件foo。命令

fooscript > foo 2>&1

在前台运行fooscript并将其输出和标准错误重定向到文件foo。在bash中,我认为这些行总是会做同样的事情。

答案 2 :(得分:3)

根据我的经验,使用2>&1的主要原因是,您希望将所有输​​出附加到文件而不是覆盖文件。使用&>语法,您无法追加。因此,使用2>&1,您可以编写类似program >> alloutput.log 2>&1的内容,并将stdout和stderr输出附加到日志文件中。

答案 3 :(得分:2)

&>foo输入的次数少于>foo 2>&1,并且不易出错(您无法以错误的顺序获取),但会获得相同的结果。

2>&1令人困惑,因为您需要将其放在1>重定向之后,除非将stdout重定向到|管道,在这种情况下,它会在...... { / p>

$ some-command 2>&1 >foo    # does the unexpected
$ some-command >foo 2>&1    # does the same as
$ some-command &>foo        # this and
$ some-command >&foo        # compatible with other shells, but trouble if the filename is numeric
$ some-command 2>&1 | less  # but the redirect goes *before* the pipe here...

答案 4 :(得分:1)

&> foo # Will take all and redirect all output to foo.

2>&1 # will redirect stderr to stdout.

答案 5 :(得分:1)

2>& 1取决于在命令行上指定的顺序。哪里&>将stdout和stderr发送到任何地方,2&​​gt;& 1将stderr发送到stdout 当前在命令行中的那一点。因此:

命令>文件2>& 1

不同于:

命令2>& 1>文件

前者将stdout和stderr重定向到文件,后者将stderr重定向到stdout重定向到文件之前的位置(在这种情况下,可能是终端。)如果你想做某事,这很有用像:

命令2>& 1>档案|少

您希望使用less来遍历stderr的输出并将stdout的输出存储到文件中。

答案 6 :(得分:0)

2>&1可能对你没有将stdout重定向到其他地方的情况很有用,而是你只想让stderr作为stdout被发送到同一个地方(比如控制台)(也许这个命令你正在运行已经将stderr发送到控制台以外的其他地方了。

答案 7 :(得分:0)

我知道这是一个非常古老的帖子..但是分享可以回答问题的内容: * ..会产生不同的行为吗?

方案: 当您尝试使用“tee”并希望在bash中使用进程替换保留退出代码时... someScript.sh 2>& 1>(tee“toALog”)#这无法捕获输出到日志

其中:

someScript.sh>& >(tee“toALog”)#工作正常!