将 stdin 从 tty1 重定向到文件后,进程仍然接受来自 tty1 的输入

将 stdin 从 tty1 重定向到文件后,进程仍然接受来自 tty1 的输入

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

我将此解释为:

  1. 标准输入是/root/file。该进程只能从/root/file 读取。
  2. 标准输出是/dev/tty1。该进程可以读取和写入/dev/tty1(尽管我不知道为什么该进程需要从它自己的输出...)
  3. 标准错误是/dev/tty1。该进程可以读取和写入/dev/tty1(同样,为什么该进程需要权限从它输出的错误日志中?)
  4. 最后一行是非标准流。我不知道它是做什么用的,但进程只能从中读取。

问题: 即使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,这在某种程度上反映了所呈现的情况...

相关内容