我想知道为什么当我们引用关闭的 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) 已关闭。