从 TTY 到 PTY,程序的输入、输出与控制
TTY 设备在 Linux 系统中的应用比较广泛,但很少有人去深度探讨 TTY 设备在整个 Linux 系统交互中起到的关键性作用。本文整合了几篇较为经典的文章对 TTY 设备整体工作原理、机制及应用的探讨,希望能够为读者带来帮助。 从功能性的角度看 其实,从功能性的角度来看,Linux 的 TTY 设备就是受操作系统管理的双向管道,用户通过外设(一般是键盘)输入的数据会进入到 TTY 设备文件,经过终端驱动,传递给操作系统进行处理,操作系统输出到 TTY 设备的数据则会被输出到外设(一般是屏幕),让用户能够看见,本质上就是一个从外设到操作系统的双向管道。 PTY 和 TTY 在功能上是一致的,不过它可以被用户进程创建。用户进程可以通过 Linux 系统提供的接口创建一个 PTS Pair,一个 PTS Pair 分为 Master 设备和 Slave 设备两种,输出到 Master 设备的数据会被传递到 Slave 设备的输入,而输出到 Slave 设备的数据会被传递到 Master 设备的输入。如果我们将显示器绑定到 Master 设备的输出上面,再将键盘绑定到 Master 设备的输入上面,那么我们就能够通过 Master 设备间接操作绑定到 Slave 设备的进程了。因为 PTY 和 TTY 本身并没有太大的差别,为避免过于啰嗦,在下面我只针对 PTY 进行讲述。 一个例子:SSH SSH 的设计中也使用了 PTY 设备,我们在通过 SSH 登入主机进入 Shell 后,可以通过 tty 命令去获取当前的 Shell 进程运行在哪个 PTY 上面。 上面tty命令给出的结果/dev/pts/dev是当前运行的 Shell 绑定的 PTY Slave 设备,而对应的 Master 设备文件描述符只有通过 /dev/ptmx创建 PTY Pair 的进程持有,都指向/dev/ptmx,可以通过sudo lsof /dev/ptmx查看。我们在使用 SSH 的时候,本地的 Terminal Emulator 将输入的字符发送到 SSH 进程,SSH 进程收到字符以后通过网络传输给服务器上面的 SSHD 进程,SSHD 进程将字符写入到 Master 设备,Shell 就能够从 Slave 设备中读取到字符。同理,Shell 的输出写入到 Slave 设备,被 SSHD 从 Master 设备处读取,通过网络传递给 SSH 客户端,最终 SSH 客户端将字符显示到屏幕上(当然,一般我们都是在 Terminal Emulator 里面运行的 SSH 进程,所以本地的 SSH 进程也是要通过 TTY 设备和键盘以及屏幕通讯的,这里图方便就没有画出来,大概样子和图 1 差不多)。 ...