&>和2>&1之间有什么区别

标准输出标准错误重定向到标准输出有两种forms。 但哪一个更好? 为什么&>被认为是完美的?

我找不到有什么区别,所以许多教程甚至bash手册说明&>更好!

那么我为什么要使用&>而不是2>&1

主要使用bash shell


编辑:感谢评论员

只有>&在csh或tcsh中工作

在ksh中只有2>&1有效。

短划线使用>文件2>&1重定向

然后使用哪一个来确保我的脚本与其他系统兼容,无论使用的shell是什么!

Bash的手册页提到有两种方法可以重定向stderr和stdout : &> file>& file 。 现在,请注意它表示stderr和stdout。

在这个>file 2>&1情况下,我们正在将stdout(1)重定向到文件,但随后还告诉stderr(2)被重定向到与stdout相同的位置! 所以目的可能是一样的,但这个想法略有不同。 换句话说,“约翰,上学;苏西去约翰去的地方”。

偏好怎么样? &>是一个bash东西。 因此,如果你正在移植一个脚本,那就不会这样做了。 但是,如果你100%肯定你的脚本只会在bash系统上运行 – 那么就没有偏好了

这是一个使用dash的例子,Debian Amquist Shell是Ubuntu的默认设置。

 $ grep "YOLO" * &> /dev/null $ grep: Desktop: Is a directory grep: Documents: Is a directory grep: Downloads: Is a directory grep: Music: Is a directory grep: Pictures: Is a directory grep: Public: Is a directory grep: Templates: Is a directory grep: Videos: Is a directory grep: YOLO: Is a directory grep: bin: Is a directory 

如您所见,stderr未被重定向

要解决问题中的编辑,可以使用if语句检查$ SHELL变量并相应地更改重定向

但对于大多数情况> file 2>&1应该工作


在更多技术术语中,forms[integer]>&word称为复制输出文件描述符 ,并且是POSIX Shell命令语言标准指定的function,大多数POSIX兼容和Brourne类shell支持该标准。

另请参阅输出重定向中的确切含义是什么?

我一般会建议遵循Borne SHell的做法,因为bash可以说是最流行的Unix shell。 Bash通常使用&>2>&1 。 恕我直言,既不是“完美”,所以我建议忘记那些废话。 实际上,你应该使用哪一个取决于你想要做什么。

2>&1将stderr与stdout合并,例如,如果要管道stderr文本,这可能很有用。 所以,例如,如果你想看一个程序是否打印某个stderr消息,但是不希望你的屏幕填满(大概)不重要的垃圾,你可以做类似于program 2>&1 | grep crashed program 2>&1 | grep crashed ,它将从一个名为“program”的程序中搜索stdout和stderr中的单词“crashed”。

另一方面,如果你不想让一个程序打印任何东西,你可以简单地运行program &> /dev/null ,它会将stderr和stdout重定向到/ dev / null,这是一个神奇的特殊文件。事情消失了。 或者,如果您想保存程序的输出(可能是为了报告错误或其他内容),您可以将stderr和stdout重定向到文件: program &> log.txt会将所有数据重定向到名为“log”的文件。文本”。 如果你愿意,你可以通过program 2> log.txt > log.txtprogram 2>&1 | cat > log.txt重定向stdout和stderr program 2>&1 | cat > log.txt program 2>&1 | cat > log.txt ,两者都与使用&>具有相同的效果。 如果您执行类似program 2>&1 > file ,则只会重定向stdout,但stderr仍然可以通过管道传输到另一个程序,例如cat,可以重定向,如上所示。 但是,输入&>比上面的任何一个例子更容易,因为它涉及输入更少的字符(并且人类阅读更容易)。 请注意, program 2> log.txt > log.txt可能更适用于非bash shell。

PS:如果你担心人们使用其他shell,你可以添加一些东西作为你的脚本的第一行称为“魔术数字”或“shebang”。 这实际上是一种确保其他计算机(特别是运行类Unix操作系统的计算机)知道用于执行脚本的程序的方法。 不同的脚本使用不同的shebang。 bb脚本的shebang看起来像这样:

 #!/bin/bash 

如果使用上面作为给定脚本的第一行,通常会使用bash来执行所述脚本。 这将使某人更难以用错误的shell意外执行脚本。

PS:我不会撒谎:到现在为止,我不知道有人可以使用>& ,但是,就bash而言,它似乎和&> 。 你每天学习新的东西。

那么我为什么要使用&>而不是2>&1

2>&1是标准的Bourne / POSIX shell。

&>是bash扩展,而不是法律上的标准。

如果你使用bash扩展编写脚本,迟早会遇到带有隐秘语法错误消息的令人头疼的失败,因为它们是在标准shell中运行的。

从Bash参考手册 – > 3.6.4重定向标准输出和标准错误 :

此构造允许将标准输出(文件描述符1)和标准错误输出(文件描述符2)重定向到名称为单词扩展的文件。

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

 &>word 

 >&word 

在这两种forms中,第一种是优选的。 这在语义上等同于

 >word 2>&1 

使用第二种forms时,单词可能不会扩展为数字或“ – ”。 如果是,则应用其他重定向运算符(请参阅下面的“复制文件描述符”)以了解兼容性原因。

也很高兴在输入和输出上引用Greg的wiki – > 4.2。 文件描述符操作 :

为方便起见,Bash还为您提供了另一种重定向forms。 &>重定向运算符实际上只是我们在这里做的更短版本[ 2>&1 ]; 将stdout和stderr重定向到文件。