从stderr获得键盘输入的更少? [英] Less gets keyboard input from stderr?

查看:134
本文介绍了从stderr获得键盘输入的更少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm taking a look at the code to the 'less' utility, specifically how it gets keyboard input. Interestingly, on line 80 of ttyin.c, it sets the file descriptor to read from:

     /*
      * 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吗?如果是这样,是什么?我以为键盘输入是通过stdin发送的.

Isn't file descriptor 2 stderr? If so, WTH?! I thought keyboard input was sent through stdin.

有趣的是,即使您执行ls -l * | less,在文件加载完成后,您仍然可以使用键盘上下滚动,但是如果您执行ls -l * | vi,则vi会大喊大叫,因为它不会从stdin读取.有什么大主意?我如何最终来到这片陌生的新大陆,在那里stderr既是向屏幕报告错误又是从键盘读取信息的一种方式?我不认为我已经不在堪萨斯州了……

Interestingly, even if you do ls -l * | less, after the file finishes loading, you can still use the keyboard to scroll up and down, but if you do ls -l * | vi, then vi will yell at you because it doesn't read from stdin. What's the big idea? How did I end up in this strange new land where stderr is both a way to report errors to the screen and read from the keyboard? I don't think I'm in Kansas anymore...

推荐答案


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

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

When logged in at an interative terminal, all three standard file descriptors point to the same thing: your TTY (or pseudo-TTY).


$ ls -fl /dev/std{in,out,err}
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdin -> fd/0
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdout -> fd/1
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stderr -> fd/2

按照惯例,我们从0读取并写入12.但是,没有什么可以阻止我们这样做.

By convention, we read from 0 and write to 1 and 2. However, nothing prevents us from doing otherwise.

当shell运行ls -l * | less时,它将创建一个从ls的文件描述符1less的文件描述符0的管道.显然,less无法再从文件描述符0中读取用户的键盘输入.它会尝试将TTY重新找回.

When your shell runs ls -l * | less, it creates a pipe from ls's file descriptor 1 to less's file descriptor 0. Obviously, less can no longer read the user's keyboard input from file descriptor 0 – it tries to get the TTY back however it can.

如果less尚未从终端上拆下,则open("/dev/tty")会给它TTY.

If less has not been detached from the terminal, open("/dev/tty") will give it the TTY.

但是,如果失败了,您该怎么办? less最后一次尝试获取TTY,假设文件描述符2附加到了文件描述符0如果未重定向的情况下将附加在同一对象上.

However, in case that fails... what can you do? less makes one last attempt at getting the TTY, assuming that file descriptor 2 is attached to the same thing that file descriptor 0 would be attached to, if it weren't redirected.

不是故障转移:


$ ls -l * | setsid less 2>/dev/null

在这里,为less提供了自己的会话(因此它不再是终端活动进程组的一部分,从而导致open("/dev/tty")失败),并且其文件描述符2也已更改–现在less立即退出,因为它正在输出到TTY,但无法获得任何用户输入.

Here, less is given its own session (so it is no longer a part of the terminal's active process group, causing open("/dev/tty") to fail), and its file descriptor 2 has been changed – now less exits immediately, because it is outputting to a TTY yet it fails to get any user input.

这篇关于从stderr获得键盘输入的更少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆