在 Lubuntu 18.04 上,我在 lxterminal 中运行一个 shell。它的控制终端是当前的伪终端从机:
$ tty
/dev/pts/2
我想知道我当前的控制终端/dev/pts/2
和/dev/tty
.
/dev/tty
就像我当前的控制终端一样/dev/pts/2
:$ echo hello > /dev/tty hello $ cat < /dev/tty world world ^C
但它们似乎是不相关的文件,而不是一个符号链接或硬链接到另一个:
$ ls -lai /dev/tty /dev/pts/2 5 crw--w---- 1 t tty 136, 2 May 31 16:38 /dev/pts/2 13 crw-rw-rw- 1 root tty 5, 0 May 31 16:36 /dev/tty
对于具有不同控制终端的不同会话,
/dev/tty
保证if是它们的控制终端。它怎么可能是不同的控制终端,而不是符号链接或硬链接?
那么它们的关系和区别是什么?任何帮助深表感谢!
第 4 节中的
tty
联机帮助页声明如下:这可以部分解释为什么
/dev/tty
不是控制终端的符号链接:它将支持附加的ioctl
,并且可能没有控制终端(但进程总是可以尝试访问/dev/tty
)。但是文档是不正确的:附加信息ioctl
不仅可以通过/dev/tty
(请参阅mosvy 的答案,这也对 的性质给出了更明智的解释/dev/tty
)。/dev/tty
可以表示不同的控制终端,而不是链接,因为实现它的驱动程序决定调用进程的控制终端是什么,如果有的话。您可以将其视为
/dev/tty
控制终端,从而提供仅对控制终端有意义的功能,而/dev/pts/2
等是普通终端,其中一个可能恰好是给定进程的控制终端。/dev/tty
是一个“神奇的”字符设备,打开时会返回当前终端的句柄。假设控制终端是
/dev/pts/1
,一个打开的文件描述符 via/dev/pts/1
和一个打开的 via/dev/tty
将引用同一个设备;任何写入、读取或其他文件操作在它们中的任何一个上都将起作用。特别是,它们将接受同一组 ioctl,而
TIOCNOTTY
不是仅通过/dev/tty
.ioctl(fd, TIOCNOTTY)
只要它是调用它的进程的控制终端,则在引用终端的任何文件描述符上都可以正常工作。描述符是通过打开
/dev/tty
,获得/dev/pts/1
的/dev/ptmx
(在这种情况下 ioctl 将作用于其对应的slave),或者最近通过调用ioctl(master, TIOCGPTPEER, flags)
.例子:
此外,它不会真正从 tty 中“分离”当前进程;该进程仍将能够从中读取,
^C
终端上的 a 将杀死它,等等。它对不是会话领导者的进程的唯一影响是 tty 将不再可以通过 访问/dev/tty
,并且将不再是列为控制 tty/proc/PID/stat
:[第 7 个字段
/proc/<pid>/stat
是控制 tty 的设备 ID,请参阅proc(5)
]如果调用它的进程是会话领导者,它会真正将会话与 tty 分离,并将
SIGHUP
/SIGCONT
对从会话发送到前台进程组。但即便如此,终端也不会关闭,并且进程仍然可以从中读取,如果它在以下情况下存活SIGHUP
:/dev/tty
不是像/dev/stdin
=>/dev/fd/0
=>/proc/self/fd/0
=>这样的符号链接/dev/pts/0
,因为它早在像 procfs 这样的虚拟动态文件系统之前就发明了(而且在一般的符号链接之前很久)。许多程序已经开始依赖于它的特定语义(例如,当控制终端不可访问时/dev/tty
失败)。ENODEV