根据schily 的这个答案,如果less
它无法打开,则从 stderr 读取导航命令/dev/tty
。
这似乎令人费解,因为我从未见过任何东西写入另一个程序的 stderr 流,而且我什至不知道我将如何做到这一点。
stderr 对读写开放的目的是什么?如果这很有用,我该如何在现代系统上使用它?(例如,是否有一些神秘的语法可以将某些内容通过管道传输到 stderr 而不是 stdin?)
根据schily 的这个答案,如果less
它无法打开,则从 stderr 读取导航命令/dev/tty
。
这似乎令人费解,因为我从未见过任何东西写入另一个程序的 stderr 流,而且我什至不知道我将如何做到这一点。
stderr 对读写开放的目的是什么?如果这很有用,我该如何在现代系统上使用它?(例如,是否有一些神秘的语法可以将某些内容通过管道传输到 stderr 而不是 stdin?)
一开始我很惊讶。但是,在阅读了答案并进行了一些调查之后,这似乎很简单。所以这就是我发现的。(最后没有惊喜。)
在重定向之前,stdin、stdout 和 stderr 按预期连接到同一设备。
因此,在大多数重定向之后(即如果 stderr)不会被重定向。stderr 仍然连接到终端。因此它可以被读取,以获得键盘输入。
唯一阻止文件在意外方向上使用的是约定,并且管道是单向的。
另一个例子,试试:
less
当尝试读取终端时,在页面之后会出错(这并不奇怪,cat
读取终端也是如此)。/dev/tty
更神秘,它不是一个链接到/proc/self
.看看我当前的控制终端和 `/dev/tty` 之间有什么关系?作为解释。感谢@StephenKitt 提供链接。
当您登录时,stdin、stdout 和 stderr 会连接到您登录的终端。更准确地说,tty 通常是打开的,stdout 和 stderr 是
dup(2)
对第一个文件描述符进行两次操作的结果。这允许从标准错误中读取,以便从终端获取输入。如另一个答案中所述,程序从 stderr读取以获得对问题的交互式回复。
由于用户无法知道程序在何种情况下从 stderr 读取,因此故意将数据从另一个程序写入 stderr 是徒劳的。
请注意,今天的程序通常首先尝试打开
/dev/tty
和使用 stderr,以防万一它不起作用。自 1979 年以来,仅从 stderr 读取的程序通常从未被修改过,此类程序通常包含以下结构:
或者
现代C编译器不接受的。因此,您今天不太可能找到一个从不打开
/dev/tty
而是从 stderr 读取交互式回复的程序。