为什么可以在 bash 下引用关闭的 stderr?

为什么可以在 bash 下引用关闭的 stderr?

我想知道为什么当我们引用关闭的 stderr 时 bash 不显示错误消息。当涉及到其他文件描述符时,如果我们想要复制它们,则必须打开它们。 Stderr 在这种情况下似乎有点特殊:

$ cat file_1
echo Test1 1>&5
$ cat file_2
echo Test2 1>&2

$ ./file_1 5>&-
./file_1: line 1: 5: Bad file descriptor
$ ./file_1 5>&1
Test1
$ ./file_2 2>&-
$ #NO ERROR and no output!
$ ./file_2
Test2

为什么外壳允许它?

答案1

运行时错误会发送到哪里file_2

当您键入./file_2(使用所述文件可执行文件)时,系统实际上运行/bin/sh ./file_2- 即它正在运行 的新副本/bin/sh,它负责运行 中的命令./file2,并报告它在那里发现的错误,将它们输出到 stderr。

/bin/sh但你刚刚在 stderr 关闭的情况下运行了它。所以想要发出错误,但无处可去。

您可以通过以下方式验证:

$ strace -e write,dup2 -fo /dev/stdout sh -c 'echo foo >&2' 2>&-
8785  dup2(2, 1)                        = -1 EBADF (Bad file descriptor)
8785  write(2, "sh: 1: ", 7)            = -1 EBADF (Bad file descriptor)
8785  write(2, "2: Bad file descriptor", 22) = -1 EBADF (Bad file descriptor)

失败dup2是因为 fd 2 已关闭,sh尝试在 stderr 上报告错误,但失败并且 stderr (fd 2) 已关闭。

相关内容