根据我对程序 IO 的了解,有stdin
、stdout
和stderr
数据流(以及返回码)。是两个数据输出流stdout
。stderr
因此,如果我使用 bash 重定向来关闭其中一个输出流,我可以缩小将文本发送到哪个流的范围。正确的?
我正在运行 Ubuntu 18.04.1 LTS,并且遇到了 bash 重定向这个奇怪的问题。
让我解释一下这个例子。这是我的命令:
# apt-cache show php5
N: Can't select versions from package 'php5' as it is purely virtual
N: No packages found
# |
该php5
软件包在 Ubuntu 18.04 上不存在,因此apt-cache
显示错误。我会假设这个文本被发送到stderr
流,所以我试图关闭那个流:
# apt-cache show php5 2>&-
# |
这似乎验证了文本是通过 发送的stderr
。到目前为止一切都很好!但现在作为健全性检查,我尝试关闭stdout
(我现在应该看到错误文本):
# apt-cache show php5 1>&-
# |
什么!?stdout
这次我重定向了,但stderr
也没有出现?
根据互联网,我的文件描述符正确:https ://www.gnu.org/software/bash/manual/html_node/Redirections.html
我不知道这里会发生什么。
截图证明:
TL;DR:不是
bash
,而是apt-cache
文件描述符乱七八糟。apt-cache
正在做一些非常有趣的事情 - 它往往不会写出以N:
用于标准输出的字符开头的行。考虑一下:
我们看到两条线,一条以 .
N:
开头E:
。N:
行转到标准输出。在您的示例中,您有两N:
行。如果您通过跟踪系统调用,
strace -e write -f bash -c 'apt-cache show randomtext >&-'
您会看到写入E:
行发生,但N
行不存在:所以
apt-cache
很聪明,可以检查重定向的标准输出。但是呢stderr
?显然写仍然存在:如果你这样做strace -e write,openat,dup2 -f bash -c 'apt-cache show randomtext 2>&-
,你会看到apt-cache
打开/dev/null
仍然有一些东西存在stderr
:如果您在 bash 中对其他程序执行相同的操作,它会按预期工作: