Mic*_*ael 13 linux ubuntu gnu-coreutils
我正在看一下'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;
Run Code Online (Sandbox Code Playgroud)
是不是文件描述符2 stderr?如果是这样,WTH ?! 我以为键盘输入是通过stdin发送的.
有趣的是,即使你这样做ls -l * | less,在文件加载完成后,你仍然可以使用键盘上下滚动,但如果你这样做ls -l * | vi,那么vi会对你大喊大叫,因为它不会从stdin读取.什么是重要的想法?我怎么会在这个奇怪的新土地上结束,stderr既可以向屏幕报告错误并从键盘读取?我不认为我在堪萨斯州了......
eph*_*ent 20
$ 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).
$ 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和写入1和2.但是,没有什么能阻止我们这样做.
当你的shell运行时ls -l * | less,它创建了一个从管道ls的文件描述符1到less的文件描述符0.显然,less不能再从文件描述符中读取用户的键盘输入0- 它会尽力恢复TTY.
如果less没有从终端分离,open("/dev/tty")将给它TTY.
但是,如果失败了......你能做什么? less最后一次尝试获取TTY,假设文件描述符2附加到文件描述符将附加到的相同内容0(如果未重定向).
这不是故障的:
$ ls -l * | setsid less 2>/dev/null
在这里,less给它自己的会话(因此它不再是终端的活动进程组的一部分,导致open("/dev/tty")失败),并且它的文件描述符2已被更改 - 现在less立即退出,因为它输出到TTY但它无法得到任何用户输入.
| 归档时间: |
|
| 查看次数: |
1238 次 |
| 最近记录: |