重定向有两种形式标准输出和标准误差进入标准输出。但是哪一个更好?为什么&>
被认为是完美的?
我找不到有什么区别,所以许多教程甚至 bash 手册都说哪个 &>
更好!
那么我为什么要使用&>
而不是2>&1
主要使用bash
shell
编辑:感谢评论者
仅 >& 在 csh 或 tcsh 中有效
在 ksh 中只有 2>&1 有效。
dash 仅使用 >file 2>&1 重定向
然后使用哪一个来确保我的脚本与其他系统兼容,无论使用的 shell 是什么!
答案1
Bash 的手册页提到有两种重定向方法stderr 和 stdout:
&> file
和>& file
。现在,请注意它同时显示了 stderr 和 stdout。
在这种情况下,>file 2>&1
我们将 stdout (1) 重定向到文件,然后告诉 stderr(2) 重定向到与 stdout 相同的位置!因此目的可能相同,但想法略有不同。换句话说,“John,去上学;Suzzie 跟着 John 去的地方”。
那首选项呢?&>
这是个bash
问题。所以如果你要移植一个脚本,那就不行了。但如果你 100% 确定你的脚本只会在带有 bash 的系统上运行 - 那么就没有首选项了
下面是一个例子dash
,它是 Ubuntu 的默认设置 Debian Amquist Shell。
$ 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
应该有效
用更专业的术语来说,这种形式[integer]>&word
被称为复制输出文件描述符,是 POSIX Shell 命令语言标准指定的功能,大多数 POSIX 兼容和 Brourne 类 shell 都支持该功能。
也可以看看输出重定向中的 & 到底是什么意思?
答案2
我一般建议遵循重生之壳的做事方式,因为 bash 可以说是目前最流行的 Unix shell。Bash 通常使用&>
或2>&1
。恕我直言,两者都不是“完美的”,所以我建议忘掉那些废话。实际上,您应该使用哪一个取决于您要做什么。
2>&1
将 stderr 与 stdout 合并,这在您想要通过管道传输 stderr 文本时非常有用。因此,例如,如果您想查看某个程序是否打印了某个 stderr 消息,但又不想让屏幕上充满(可能)不重要的垃圾,您可以执行类似 的操作program 2>&1 | grep crashed
,它将在名为“program”的程序的 stdout 和 stderr 中搜索单词“crashed”。
另一方面,如果您根本不想让程序打印任何内容,您可以简单地运行program &> /dev/null
,它将把 stderr 和 stdout 重定向到 /dev/null,这是一个神奇地让东西消失的特殊文件。或者,如果您想保存程序的输出(可能是为了报告错误或其他问题),您可以将 stderr 和 stdout 重定向到一个文件:program &> log.txt
将所有数据重定向到名为“log.txt”的文件。如果您愿意,您可以通过program 2> log.txt > log.txt
或重定向 stdout 和 stderr program 2>&1 | cat > log.txt
,这两种方法的效果与使用 相同&>
。如果您执行类似 的操作program 2>&1 > file
,则只有 stdout 会被重定向,但 stderr 仍可以通过管道传输到另一个程序,例如 cat,它可以像上面所示那样重定向。但是,输入&>
比上述任何示例都更容易,因为它涉及输入更少的字符(而且对人类来说更容易阅读)。请注意,这program 2> log.txt > log.txt
可能更有可能在非 bash shell 上工作。
附言:如果您担心人们使用其他 shell,您可以在脚本的第一行添加一个称为“魔法数字”或“shebang”的内容。这本质上是一种确保其他计算机(特别是运行类 Unix 操作系统的计算机)知道使用哪个程序来执行脚本的方法。不同的脚本使用不同的 shebang。bash 脚本的 shebang 如下所示:
#!/bin/bash
如果您使用上述内容作为给定脚本的第一行,则通常会使用 bash 来执行该脚本。这将使某人更难意外使用错误的 shell 执行脚本。
附言:我不会撒谎:直到现在,我都不知道可以使用>&
,但就 bash 而言,它似乎可以做同样的事情&>
。你每天都会学到新东西。
答案3
那么为什么我要使用 &> 而不是 2>&1
2>&1
是标准 Bourne/POSIX shell。
&>
是 bash 扩展,而不是法律上标准。
如果您使用 bash 扩展编写脚本,迟早您会遇到令人头疼的失败和神秘的语法错误消息,因为它们是在标准 shell 中运行的。
答案4
从Bash 参考手册 -> 3.6.4 重定向标准输出和标准错误:
此构造允许将标准输出(文件描述符 1)和标准错误输出(文件描述符 2)重定向到名称为 word 扩展的文件。
重定向标准输出和标准错误有两种格式:
&>word
和
>&word
在这两种形式中,第一种是优选的。这在语义上等同于
>word 2>&1
使用第二种形式时,word 可能不会扩展为数字或“-”。如果是这样,出于兼容性原因,将应用其他重定向运算符(请参阅下面的复制文件描述符)。
也值得参考Greg 的 wiki 关于输入和输出 -> 4.2. 文件描述符操作:
为了方便起见,Bash 还提供了另一种形式的重定向。&> 重定向运算符实际上只是我们在此处执行的操作 [
2>&1
] 的简化版本;将 stdout 和 stderr 都重定向到一个文件。