【发布时间】:2020-07-09 02:16:37
【问题描述】:
据我了解,“/dev/null 2>&1”使程序静默(整个输出和错误被抑制)。 那么没有 /dev/null 的 "2>&1" 呢? 例如,
ls -ld /tmp /tnt 2>&1
没有/dev/null 的“2>&1”的实际用法是什么?这有什么意义吗? (它给出完全相同的输出:
ls -ld /tmp /tnt)
【问题讨论】:
据我了解,“/dev/null 2>&1”使程序静默(整个输出和错误被抑制)。 那么没有 /dev/null 的 "2>&1" 呢? 例如,
ls -ld /tmp /tnt 2>&1
没有/dev/null 的“2>&1”的实际用法是什么?这有什么意义吗? (它给出完全相同的输出:
ls -ld /tmp /tnt)
【问题讨论】:
2>&1 表示将stdout 和stderr 重定向到同一个文件。
这通常有助于调试。
【讨论】:
2>&1 所做的是将错误消息发送到标准输出流。
神秘符号的含义是更长的解释。
一个进程有两个特殊的输出流,称为“标准输出”(用于常规输出)和“标准错误”(用于错误消息)。它们是分开的,因此即使您将常规输出重定向到文件,程序也可以在终端上报告错误。
任何打开的文件流都有一个与之关联的数字,这个数字称为“文件描述符”(简称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>&1 将foo 和/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: /';
【讨论】: