我们什么时候在实践中使用“2>&1”?

When do we use of "2>&1" in practice?

据我了解,“/dev/null 2>&1”使程序静音(整个输出和错误都被抑制)。 那么没有 /dev/null 的 "2>&1" 呢? 例如,

ls -ld /tmp /tnt 2>&1

没有/dev/null的“2>&1”有什么实际用途?这有意义吗? (它提供与以下内容完全相同的输出:

ls -ld /tmp /tnt )

2>&1 表示将 stdoutstderr 重定向到同一个文件。

这对平时调试很有帮助。

2>&1 的作用是使错误消息进入标准输出流。

神秘符号的含义是一个更长的解释。

一个进程有两个特殊的输出流,称为"standard output"(用于常规输出)和"standard error"(用于错误消息)。它们是分开的,因此即使您将常规输出重定向到文件,程序也可以在终端上报告错误。

任何打开的文件流都有一个与之关联的数字,这个数字称为"file descriptor"(简称fd)。这就是操作系统如何跟踪进程正在使用的文件。标准输出得到数(文件描述符)1,标准错误得到数(fd)2.

2>&1 将文件描述符 2 设置为文件描述符 1 的副本。如果您已将输出重定向到 /dev/null 之类的文件,fd 1 指的是一个打开的文件,这将使 fd 2 引用同一个打开的文件。

"/dev/null 2>&1" makes the program silent是不正确的。单独来看,该表达式是不完整的。例如,echo foo /dev/null 2>&1foo/dev/null 作为参数传递给 echo 并运行 echo 并将其 stderr 流重定向到其 stdout。另一方面,更常见的是:

echo foo > /dev/null 2>&1

将 stdout 重定向到 /dev/null,然后将 stderr 重定向到 stdout(现在是 /dev/null,所以两个流都转到 /dev/null)。请注意顺序很重要,echo foo 2>&1 > /dev/null 会将错误写入调用进程的标准输出,同时将输出写入 /dev/null。

使用这种流复制的一个常见原因是当您想要控制输出和错误的位置时。例如,如果你想对 stderr 应用过滤器,你可以丢弃输出并过滤错误:

cmd 2>&1 > /dev/null | sed 's/^/ERROR: /g' >&2

这是一个简单的示例,仅用于演示。要将过滤器独立应用于两个流,您可以执行以下操作:

{ cmd 2>&1 >&3 | sed 's/^/ERROR: /' >&2; } 3>&1 | sed 's/^/OUT:   /';