如何(以及为什么)使用 stderr 进行读取和写入?

如何(以及为什么)使用 stderr 进行读取和写入?

根据希利的这个回答less如果无法打开,则从 stderr 读取导航命令/dev/tty

这似乎令人费解,因为我从未见过任何东西写入另一个程序的 stderr 流,而且我不知道如何实现这一点。

stderr 开放读写的目的是什么?如果这有用,我如何在现代系统上使用它? (例如,是否有一些神秘的语法可以将某些内容通过管道传输到 stderr 而不是 stdin ?)

答案1

一开始我很惊讶。然而,在阅读了答案并做了一些调查后,这似乎很简单。这就是我发现的。 (最后没有什么意外。)

在重定向之前,stdin、stdout 和 stderr 按预期连接到同一设备。

#ctrl-alt-delor:~$
#↳ ll /dev/std*
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdout -> /proc/self/fd/1

#ctrl-alt-delor:~$
#↳ ll /proc/self/fd/*
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/0 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/1 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/2 -> /dev/pts/12

因此,大多数重定向(即 stderr)之后不会被重定向。 stderr 仍然连接到终端。因此可以读取它,以获得键盘输入。

唯一阻止文件以意外方向使用的因素是约定,并且管道是单向的。

另一个例子,尝试:

cat | less

当尝试读取终端时,在翻页后会出现错误less(这并不奇怪,cat读取终端也是如此)。

/dev/tty更神秘的是,它不是链接进去的/proc/self

#ctrl-alt-delor:~$
#↳ ll /dev/tty
crw-rw-rw- 1 root tty 5, 0 Jun 29 09:18 /dev/tty

我当前的控制终端和`/dev/tty`之间有什么关系?进行解释。感谢@StephenKitt 提供的链接。

答案2

dup(2)当您登录时,stdin、stdout 和 stderr 将连接到您登录的终端。更准确地说,tty 通常会打开,stdout 和 stderr 是对第一个文件描述符进行两次操作的结果。这允许从 stderr 读取以便从终端获取输入。

正如另一个答案中提到的,程序来自 stderr 以获得问题的交互式答复。

由于用户无法知道程序在什么情况下从 stderr 读取数据,因此故意从另一个程序向 stderr 写入数据是无用的尝试。

请注意,今天的程序通常首先尝试打开/dev/tty并使用 stderr,仅在不起作用的情况下。

仅从 stderr 读取的程序通常自 1979 年以来从未被修改过,此类程序通常包含如下结构:

int i 1;

或者

i =* 2;

现代 C 编译器不接受。因此,您今天不太可能找到一个永远不会打开/dev/tty而是读取来自 stderr 的交互式回复的程序。

相关内容