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


12

根据此答案由席利less从标准错误读取导航命令,如果它不能够打开/dev/tty

这似乎令人困惑,因为我从未见过任何东西可以写入另一个程序的stderr流,而且我什至不知道该如何完成。

stderr对阅读和书写开放的目的是什么?如果这有用,我如何在现代系统上使用它?(例如,是否存在一些奥术语法可将某些内容传递到stderr而不是stdin中?)

Answers:


7

起初我很惊讶。但是,在阅读了答案并进行了一些调查之后,这似乎很简单。这就是我所发现的。(最后没有惊喜。)

重定向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提供的链接。


关于/dev/tty,看这个问题
Stephen Kitt

6

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

如在另一个答案中提到的,程序从stderr 读取以获取对问题的交互式答复。

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

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

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

int i 1;

要么

i =* 2;

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


因此,如果我理解正确,stderrstdin重定向(通过管道或其他方式)时,shell连接到tty 吗?或者只是始终连接stderr到tty?
Draconis

1
登录时,stderr已连接到您的登录终端。
schily

2
i =+ 1是完全有效的C,等于i = (+1)。当然,前者是参加C比赛的好人选。
G. Sliepen

1
好的,可能只是创建了警告。我在1977
。– schily

1
似乎我知道更多的shell,因为确实知道至少有一个shell从标准输入之外读取。(-:
JdeBP '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.