May*_*hux 38 command-line bash redirect
有两种形式将标准输出和标准错误重定向到标准输出。但哪个更好?为什么&>被认为是完美的?
我找不到有什么区别,所以很多教程甚至 bash 手册都说 &>更好!
所以我为什么要使用&>而不是2>&1
主要使用bashshell
编辑:感谢评论者
只有 >& 适用于 csh 或 tcsh
在 ksh 中只有 2>&1 有效。
破折号仅使用 >file 2>&1 重定向
然后使用哪一个来确保我的脚本与其他系统兼容,无论使用的 shell 是什么!
Ser*_*nyy 29
Bash 的手册页提到有两种方法可以重定向stderr 和 stdout :
&> file 和>& file. 现在,请注意它同时表示 stderr 和 stdout。
在这种情况下,>file 2>&1我们正在将 stdout (1) 重定向到文件,但同时也告诉 stderr(2) 重定向到与 stdout 相同的位置!所以目的可能是一样的,但想法略有不同。换句话说,“约翰,去上学;苏西去约翰去的地方”。
偏好呢?&>是bash一回事。因此,如果您要移植脚本,则不会这样做。但是,如果您 100% 确定您的脚本只能在使用 bash 的系统上运行 - 那么就没有偏好
这是一个带有dashDebian 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
Run Code Online (Sandbox Code Playgroud)
如您所见,stderr 没有被重定向
为了解决您在问题中的编辑,您可以使用 if 语句来检查 $SHELL 变量并相应地更改重定向
但对于大多数情况> file 2>&1应该工作
在更专业的术语中,该表单[integer]>&word称为Duplicating Output File Descriptor,是 POSIX Shell 命令语言标准指定的功能,大多数 POSIX 兼容和类似 Bourne 的 shell 都支持该功能。
TSJ*_*117 10
我通常建议遵循Bourne-again SHell的做事方式,因为 bash 可以说是最流行的 Unix shell。Bash 通常使用&>或2>&1。恕我直言,两者都不是“完美”的,所以我建议忘记那些废话。实际上,您应该使用哪一个取决于您要尝试做什么。
2>&1将 stderr 与 stdout 合并,例如,如果您想通过管道传输 stderr 文本,这会很有用。因此,例如,如果您想查看程序是否打印了某个 stderr 消息,但又不想让您的屏幕充满(大概)不重要的垃圾,您可以执行类似的操作program 2>&1 | grep crashed,它将从程序中搜索 stdout 和 stderr “崩溃”这个词被称为“程序”。
另一方面,如果您根本不希望程序打印任何内容,您可以简单地运行program &> /dev/null,它将把 stderr 和 stdout 都重定向到 /dev/null,这是一个神奇地使事情消失的特殊文件。或者,如果您想保存程序的输出(也许是报告错误或其他内容),您可以将 stderr 和 stdout 都重定向到一个文件:program &> log.txt将所有数据重定向到一个名为“log.txt”的文件。如果你愿意,你可以通过program 2> log.txt > log.txtor重定向 stdout 和 stderr program 2>&1 | cat > log.txt,这两者的效果与使用&>. 如果您执行类似的操作program 2>&1 > file,则只会重定向 stdout,但仍然可以通过管道将 stderr 传送到另一个程序,例如 cat,它可以如上所示重定向。但是,键入&>比上面任何一个例子都容易,因为它涉及输入更少的字符(而且人类阅读更容易)。请注意,这program 2> log.txt > log.txt可能更可能适用于非 bash shell。
PS:如果您担心人们使用其他 shell,您可以在脚本的第一行添加一些称为“magic number”或“shebang”的内容。这本质上是一种确保其他计算机(尤其是运行类 Unix 操作系统的计算机)知道使用哪个程序来执行脚本的方法。不同的脚本使用不同的shebang。bash 脚本的shebang 如下所示:
#!/bin/bash
Run Code Online (Sandbox Code Playgroud)
如果您将上述内容用作给定脚本的第一行,则通常会使用 bash 来执行该脚本。这将使某人意外地使用错误的 shell 执行脚本变得更加困难。
PS:我不会撒谎:到目前为止,我不知道有人可以使用>&,但是,就 bash 而言,它似乎与&>. 你每天学习新的东西。
来自Bash 参考手册 -> 3.6.4 重定向标准输出和标准错误:
\n\n\n\n\n此构造允许将标准输出(文件描述符 1)和标准错误输出(文件描述符 2)重定向到名称为单词扩展的文件。
\n\n重定向标准输出和标准错误有两种格式:
\n\nRun Code Online (Sandbox Code Playgroud)\n\n&>word\n和
\n\nRun Code Online (Sandbox Code Playgroud)\n\n>&word\n在这两种形式中,优选第一种。这在语义上相当于\n
\n\nRun Code Online (Sandbox Code Playgroud)\n\n>word 2>&1\n使用第二种形式时,单词可能不会扩展为数字或 \xe2\x80\x98-\xe2\x80\x99。如果确实如此,则出于兼容性原因,将应用其他重定向运算符(请参阅下面的复制文件描述符)。
\n
也可以参考Greg 的 wiki 输入和输出 -> 4.2。文件描述符操作:
\n\n\n\n为了方便起见,Bash 还为您提供了另一种形式的重定向。&> 重定向运算符实际上只是我们在这里所做的操作的较短版本 [
\n2>&1]; 将 stdout 和 stderr 重定向到文件。
那么为什么我要使用 &> 而不是 2>&1
2>&1 是标准的 Bourne/POSIX shell。
&>是 bash 扩展而不是法律上的标准。
如果您使用 bash 扩展编写脚本,迟早您会遇到令人头疼的失败并带有神秘的语法错误消息,因为它们是在标准 shell 中运行的。