为什么这不重定向到 /dev/null?

Why doesn't this redirect to /dev/null?

也许是晚了,我脑子放屁了,但不应该这样吗

(>&2 echo dying) 2>&1 >/dev/null

正常情况下不产生输出shell?

同样如果这是/tmp/x.pl

#!/usr/bin/perl
die "dying"

那为什么会这样

#> perl /tmp/x.pl 2>&1 >/dev/null

输出

dying at /tmp/x.pl line 2.

?

文件描述符重定向的执行顺序非常重要。

只需调换顺序:

(>&2 echo dying) >/dev/null 2>&1
perl /tmp/x.pl >/dev/null 2>&1

当你在做的时候:

(>&2 echo dying) 2>&1 >/dev/null

subshell (()) 的 STDOUT 被重定向到 subshell 的 STDERR 最先出现的地方。然后在父(主)shell 中,您已将 STDERR 重定向到 STDOUT,此时它指向终端,因此来自子 shell 的 STDERR 将被打印,然后您正在重定向 STDOUT到 /dev/null,它将从评估的那一刻起将 STDOUT 发送到 /dev/null,而不是之前。

第二种情况也有类似的说明。

因此,在操作文件描述符时始终保持顺序,如果从左到右则计算顺序。

重定向是从左到右处理的。所以你在2>&1之前>/dev/null。这会将 FD 2 重定向到 FD 1 的原始连接(大概是终端),然后将 FD 1 重定向到 /dev/null。 FD 2 仍然连接到终端。

要将 stdoutstderr 都重定向到 /dev/null,您必须使用

(>&2 echo dying) >/dev/null 2>&1