14

我正在查看“less”实用程序的代码,特别是它如何获取键盘输入。有趣的是,在 ttyin.c 的第 80 行,它将文件描述符设置为从以下位置读取:

     /*
      * Try /dev/tty.
      * If that doesn't work, use file descriptor 2,
      * which in Unix is usually attached to the screen,
      * but also usually lets you read from the keyboard.
      */
  #if OS2
      /* The __open() system call translates "/dev/tty" to "con". */
      tty = __open("/dev/tty", OPEN_READ);
  #else
      tty = open("/dev/tty", OPEN_READ);
  #endif
      if (tty < 0)
          tty = 2;

文件描述符不是 2 stderr 吗?如果是这样,WTH?!我认为键盘输入是通过标准输入发送的。

有趣的是,即使你这样做ls -l * | less了,在文件加载完成后,你仍然可以使用键盘上下滚动,但如果你这样做了ls -l * | vi,那么 vi 就会对你大喊大叫,因为它不是从 stdin 读取的。有什么大主意?我是如何进入这个陌生的新领域的,stderr 既是向屏幕报告错误又是从键盘读取的一种方式?我想我已经不在堪萨斯了...

4

4 回答 4

20
$ ls -l /dev/fd/
lrwx------ 1 我我 64 2009-09-17 16:52 0 -> /dev/pts/4
lrwx------ 1 我我 64 2009-09-17 16:52 1 -> /dev/pts/4
lrwx------ 1 我我 64 2009-09-17 16:52 2 -> /dev/pts/4

在交互式终端登录时,所有三个标准文件描述符都指向同一个东西:您的 TTY(或伪 TTY)。

$ ls -fl /dev/std{输入、输出、错误}
lrwxrwxrwx 1 根 4 2009-09-13 01:57 /dev/stdin -> fd/0
lrwxrwxrwx 1 根 4 2009-09-13 01:57 /dev/stdout -> fd/1
lrwxrwxrwx 1 根 4 2009-09-13 01:57 /dev/stderr -> fd/2

按照惯例,我们读取0和写入1and 2。然而,没有什么能阻止我们做其他事情。

当您的 shell 运行时,它会创建一个从文件描述符到文件描述符ls -l * | less的管道。显然,不能再从文件描述符中读取用户的键盘输入——它会尝试取回 TTY,但它可以。ls1less0less0

如果less还没有从终端上分离出来,open("/dev/tty")就会给它TTY。

但是,如果失败了……你能做什么? less最后一次尝试获取 TTY,假设文件描述符附加到文件描述符将2附加到的同一事物0上,如果它没有被重定向。

不是万无一失的:

$ ls -l * | 设置少 2>/dev/null

在这里,less给定了它自己的会话(因此它不再是终端的活动进程组的一部分,导致open("/dev/tty")失败),并且它的文件描述符2已更改 - 现在less立即退出,因为它正在输出到 TTY 但它未能获取任何用户输入。

于 2009-09-17T21:08:50.713 回答
3

嗯...首先,您似乎错过了open()打开“/dev/tty”的电话。如果对 open() 的调用失败,它只使用文件描述符 2。在标准的 Linux 系统上,可能还有很多 Unices,'/dev/tty' 存在并且不太可能导致失败。

其次,顶部的注释提供了有限的解释,说明它们为什么会回退到文件描述符 2。我的猜测是,无论如何stdinstdout, 和stderr几乎都与 '/dev/tty/' 相关联,除非重定向。并且由于 stdin 和/或 stdout 的最常见重定向(通过管道或</ >),但不太常见于stderr,因此使用stderr最有可能仍然连接到“键盘”。

于 2009-09-17T20:59:11.963 回答
2

最终来自提问者的答案的相同问题在linuxquestions上,尽管他们引用的来源略有不同less。不,我大部分都不懂,所以我无能为力:)

于 2009-09-17T21:01:07.530 回答
-2

它似乎是向 FD 2 发送键盘输入的 Linux 特定功能。

于 2009-09-17T21:02:23.533 回答