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

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

重定向有两种形式标准输出标准误差进入标准输出。但是哪一个更好?为什么&>被认为是完美的?

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

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

主要使用bashshell


编辑:感谢评论者

仅 >& 在 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 都重定向到一个文件。

相关内容