command < file
用于将文件中的内容重定向到命令中。
在虚拟终端 1 (/dev/tty1) 上,我运行less < file
.然后在另一个虚拟终端上运行lsof -p <pid of the less process>
并查看(修剪后的)输出:
FD name
----------------
0r /root/file
1u /dev/tty1
2u /dev/tty1
3r /dev/tty
我将此解释为:
- 标准输入是/root/file。该进程只能从/root/file 读取。
- 标准输出是/dev/tty1。该进程可以读取和写入/dev/tty1(尽管我不知道为什么该进程需要读从它自己的输出...)
- 标准错误是/dev/tty1。该进程可以读取和写入/dev/tty1(同样,为什么该进程需要权限读从它输出的错误日志中?)
- 最后一行是非标准流。我不知道它是做什么用的,但进程只能从中读取。
问题:
即使stdin
是 /root/file,我仍然可以与该less
进程交互(例如,输入“/”进入搜索模式并搜索单词)。这意味着该进程仍然接受来自当前虚拟终端(/dev/tty1)的输入。我认为由于stdin
不是 /dev/tty1,我应该无法less
通过键盘输入与进程交互?
答案1
标准输入是/root/file。该进程只能从/root/file 读取。
标准输出是/dev/tty1。该进程可以读取和写入 /dev/tty1 (尽管我不知道为什么该进程需要读取自己的输出......)
标准错误是/dev/tty1。该进程可以读取和写入 /dev/tty1(同样,为什么该进程需要读取它输出的错误日志的权限?)
“stdout”和“stderr”都指向同一个文件对象,相同的“stdin”在从 重定向之前指向/root/file
,即/dev/tty1
.它们都是通过以下方式获得的重复(2)相同的文件描述符,并共享它们的所有属性(模式:O_RDWR
、文件指针等)。您应该将文件描述符视为一组(引用计数)指针中的索引,其中多个指针可以指向同一结构。当 shellfcntl(fd, F_SETFL, O_WRONLY)
重定向 stdin 时,它不会费心去改变“stdout”和“stderr”的访问模式file
——那是毫无意义的。
最后一行是非标准流。我不知道它是做什么用的,但进程只能从中读取。
这就是less
用于用户交互的。
问题:即使标准输入是 /root/file,我仍然可以与 less 进程交互(例如,输入“/”进入搜索模式并搜索单词)。这意味着该进程仍然接受来自当前虚拟终端(/dev/tty1)的输入。我认为由于标准输入不是 /dev/tty1,我应该无法通过在键盘上打字与 less 进程进行交互?
/dev/tty
是一条永远打开控制终端的魔法路径;在你的情况下,/dev/tty
并/dev/tty1
指同一个设备(可能是虚拟设备——伪终端)
答案2
你正在表现出一种特殊的情况。虽然less
在 fd 0 上的输入流上工作,但它需要一个输入通道来与用户交互。因此它会打开另一个文件(此处为 fd 3)以从键盘读取。这绝对不是标准输入。旁白(回忆...):在 DEC 的 OpenVMS 上,默认情况下,它们区分 SYS$INPUT 和 SYS$COMMAND,这在某种程度上反映了所呈现的情况...