正如大多数人已经做过很多次一样,使用less
以下命令查看长文本很方便:
some_command | less
Run Code Online (Sandbox Code Playgroud)
现在它的标准输入连接到一个管道(FIFO)。它怎么还能读取像 up/down/quit 这样的命令?
Ste*_*itt 53
正如William Pursell所提到的,less
从终端读取用户的击键。它明确地打开/dev/tty
,控制终端;这给了它一个文件描述符,与标准输入分开,它可以从中读取用户的交互式输入。如有必要,它可以同时从其标准输入读取数据以显示。(如有必要,它也可以直接写入终端。)
您可以通过运行看到这种情况发生
some_command | strace -o less.trace -e open,read,write less
Run Code Online (Sandbox Code Playgroud)
移动 input, exitless
并查看 : 的内容,less.trace
您将看到它 open /dev/tty
,并从文件描述符 0 和打开时返回的任何一个/dev/tty
(可能是 3)中读取。
对于希望确保它们正在从终端读取和写入终端的程序来说,这是一种常见的做法。一个例子是 SSH,例如,当它要求输入密码或密码时。
正如schily所解释的,如果无法打开,将从其标准错误(文件描述符 2)中读取。的使用是在 1991 年 4 月 2 日发布的版本 177 中引入的。/dev/tty
less
less
/dev/tty
如果您尝试运行cat /dev/tty | less
,如Hagen von Eitzen所建议的那样,将成功打开,但在关闭它之前不会从中获得任何输入。所以你会看到屏幕空白,直到你按下杀死(或以其他方式杀死它);then将显示您在运行时输入的任何内容,并允许您控制它。less
/dev/tty
cat
CtrlCcat
less
cat
sch*_*ily 28
UNIX 提供了两种方法来读取用户输入,而 stdin 已被重定向:
原始方法是从stderr读取。标准错误是开放的写作和阅读,这仍然是POSIX提及。
后来的 UNIX 版本(大约 1979 年)添加了一个/dev/tty
驱动程序接口,允许打开进程的控制 tty。由于存在没有控制 tty 的进程,因此打开尝试可能会/dev/tty
失败。因此,友好的编写软件会退回到原始方法,然后尝试从 stderr 读取。