2>&-、2>/dev/null、|&、&>/dev/null 和 >/dev/null 2>&1 之间的区别

2>&-、2>/dev/null、|&、&>/dev/null 和 >/dev/null 2>&1 之间的区别

只是寻找之间的区别

  • 2>&-
  • 2>/dev/null
  • |&
  • &>/dev/null
  • >/dev/null 2>&1

以及它们与非 Bourne shell(如tcshmksh等)的可移植性。

答案1

背景:

  • A1号= 标准输出(即 STDOUT)
  • A2号= 标准错误(即 STDERR)
  • 如果没有明确给出数字,那么1号由 shell (bash) 假定

首先让我们解决它们的功能。作为参考,请参阅高级 Bash 脚本指南

功能

2>&-

这个的一般形式是M>&-,其中“M”是文件描述符号。这将关闭引用的文件描述符的输出,即“M”

2>/dev/null

这个的一般形式是M>/dev/null,其中“M”是文件描述符号。这将重定向文件描述符,“M”, 到/dev/null

2>&1

这个的一般形式是M>&N,其中“M”&“N”是文件描述符编号。它结合了文件描述符的输出“M”“N”到单个流中。

|&

这只是 的缩写2>&1 |。它是在 Bash 4 中添加的。

&>/dev/null

这只是 的缩写>/dev/null 2>&1。它将文件描述符 2 (STDERR) 和描述符 1 (STDOUT) 重定向到/dev/null.

>/dev/null

这只是 的缩写1>/dev/null。它将文件描述符 1 (STDOUT) 重定向到/dev/null.

可移植到非 bash、tcsh、mksh 等。

我没有过多处理过csh和之外的其他 shell tcsh。与 bash 的重定向操作符相比,我对这两个操作的经验是 bash 在这方面更胜一筹。请参阅tcsh 手册页更多细节。

csh/tcsh 不直接支持您询问的命令。您必须使用不同的语法来构造类似的函数。

答案2

这是为了重定向 STDERR 和 STDOUT:

  • 2>/dev/null

    将 STDERR 重定向到 /dev/null (防止显示在控制台上)

  • |&

    将 STDERR 和 STDOUT 重定向到管道命令的 STDIN (cmd1 |& cmd2)

  • &>/dev/null

    将 STDERR 和 STDOUT 重定向到 /dev/null (控制台上没有显示任何内容)

  • >/dev/null

    将 STDOUT 重定向到 /dev/null (控制台上仅显示 STDERR)

  • 2>&-

    用于关闭与重定向一起使用的文件描述符

这些都是 Bourne shell 的标准重定向方法。

答案3

将此视为所选答案的附录。您可能想知道哪些形式是 POSIX,哪些不是。

涉及两种 POSIX 形式:

2.7.2 重定向输出

重定向输出的两种通用格式是:

[n]>单词

[n]>|字

其中可选的 n 表示文件描述符编号。如果省略该数字,则重定向应引用标准输出(文件描述符 1)。

如果设置了 noclobber 选项(请参阅 set -C 的说明)并且由单词扩展命名的文件存在并且是常规文件,则使用“>”格式的输出重定向将失败。否则,使用“>”或“>|”重定向格式应导致名称由单词扩展产生的文件被创建并打开以在指定的文件描述符上输出,如果未指定,则为标准输出。如果该文件不存在,则创建该文件;否则,打开后将被截断为空文件。

-

2.7.6 复制输出文件描述符

重定向运算符:

[n]>&词

应从另一个输出文件描述符复制一个输出文件描述符,或应关闭一个输出文件描述符。如果 word 的计算结果为一位或多位数字,则 n 表示的文件描述符或标准输出(如果未指定 n)应成为 word 表示的文件描述符的副本;如果 word 中的数字不代表已打开用于输出的文件描述符,则会导致重定向错误;请参阅 Shell 错误的后果。如果 word 的计算结果为“-”,则关闭文件描述符 n 或标准输出(如果未指定 n)。尝试关闭未打开的文件描述符不应构成错误。如果 word 的计算结果为其他内容,则行为未指定。

所以:

Function      POSIX-compat    POSIX 
2>&-          Yes             close 
2>/dev/null   Yes             redir
2>&1          Yes             dup 
|&            No              
&>/dev/null   No
>/dev/null    Yes             redir
>&/dev/null   ?               ?dup

最后一行不在原始问题中,但它在 bash 中毫无抱怨地工作。 (也可以使用 /dev/tty 代替 /dev/null)。

相关内容