Linux 伪终端(pty)

通过《Linux 终端(TTY)》一文我们了解到:我们常说的终端分为终端 tty1-6 和伪终端。使用 tty1-6 的情况一般为 Linux 系统直接连了键盘和显示器,或者是使用了 vSphere console 等虚拟化方案,其它情况下使用的都是伪终端。本文将介绍伪终端的基本概念。本文中演示部分使用的环境为 ubuntu 18.04。

伪终端(pseudo terminal,有时也被称为 pty)是指伪终端 master 和伪终端 slave 这一对字符设备。其中的 slave 对应 /dev/pts/ 目录下的一个文件,而 master 则在内存中标识为一个文件描述符(fd)。伪终端由终端模拟器提供,终端模拟器是一个运行在用户态的应用程序。

Master 端是更接近用户显示器、键盘的一端,slave 端是在虚拟终端上运行的 CLI(Command Line Interface,命令行接口)程序。Linux 的伪终端驱动程序,会把 master 端(如键盘)写入的数据转发给 slave 端供程序输入,把程序写入 slave 端的数据转发给 master 端供(显示器驱动等)读取。请参考下面的示意图(此图来自互联网):

我们打开的终端桌面程序,比如GNOME终端,实际上是一种终端仿真软件。当终端仿真软件运行时,它通过打开/dev/ptmx文件创建一个伪终端主从机对,并让外壳在从机端运行。当用户按下终端仿真软件中的键盘按钮时,生成一个字节流并将其写入主机,外壳进程可以读取从机的输入;外壳及其子程序将输出写入从机,终端仿真软件负责将字符打印到窗口中。

[En]

The terminal desktop program we open, such as GNOME Terminal, is actually a kind of terminal emulation software. When the terminal emulation software is running, it creates a pseudo-terminal master and slave pair by opening the / dev/ptmx file, and lets shell run on the slave side. When the user presses the keyboard button in the terminal simulation software, it generates a byte stream and writes it into master, and the shell process can read the input from slave; shell and its subroutines write the output into slave, and the terminal simulation software is responsible for printing characters into the window.

伪终端的使用场景大约有三种:

[En]

There are about three types of usage scenarios for pseudo-terminals:

  • 像 xterm、gnome-terminal 等图形界面的终端模拟软件将键盘和鼠标事件转换为文本输入,并图形化地显示输出内容
  • 远程 shell 应用程序(如 sshd)在客户机上的远程终端和服务器上的伪终端之间中继输入和输出
  • 屏幕和tmux等多路复用器应用。它们将输入和输出从一个终端转发到另一个终端,将文本模式应用程序与实际终端分离。
    [En]

    Multiplexer applications such as screen and tmux. They relay inputs and outputs from one terminal to another, detaching text-mode applications from the actual terminal.*

Linux 中为什么要提出伪终端这个概念呢?shell 等命令行程序不可以直接从显示器和键盘读取数据吗?
为了在同一块屏幕上运行多个终端模拟器并远程登录,外壳真的不可能直接跨越伪终端层。在操作系统的主要思想–虚拟化的指导下,需要将多个虚拟终端分配给多个终端模拟器和远程用户。上图中的外壳使用的从机端是一个虚拟终端。主控端模拟用户端的交互。它之所以被称为虚拟终端,是因为它不仅转发数据流,而且看起来像终端。

[En]

In order to run multiple terminal emulators on the same screen and log in remotely, it is really impossible for shell to cross the pseudo-terminal layer directly. Under the guidance of virtualization, a major idea of the operating system, it is necessary to assign multiple virtual terminals to multiple terminal simulators and remote users. The slave side used by shell in the figure above is a virtualized terminal. The Master side simulates the interaction of the user side. The reason why it is called a virtual terminal is that it not only forwards the data stream, but also looks like a terminal.

伪终端本质上是由在用户模式下运行的终端模拟器创建的一对字符设备。从服务器对应于/dev/pt/目录中的一个文件,而主服务器被标识为内存中的文件描述符(Fd)。对于伪终端来说,关键是软件仿真终端程序运行在用户空间,这是它与终端的本质区别。请参考下图:

[En]

A pseudo terminal is essentially a pair of character devices created by a terminal simulator running in user mode. The slave corresponds to a file in the / dev/pts/ directory, while the master is identified as a file descriptor (fd) in memory. For the pseudo-terminal, the key point is that the software simulation terminal program runs in the user space, which is the essential difference between it and the terminal. Please refer to the following diagram:

/dev/ptmx 是一个字符设备文件,当进程打开 /dev/ptmx 文件时,进程会同时获得一个指向 pseudoterminal master(ptm)的文件描述符和一个在 /dev/pts 目录中创建的 pseudoterminal slave(pts) 设备。通过打开 /dev/ptmx 文件获得的每个文件描述符都是一个独立的 ptm,它有自己关联的 pts,ptmx(可以认为内存中有一个 ptmx 对象)在内部会维护该文件描述符和 pts 的对应关系,对这个文件描述符的读写都会被 ptmx 转发到对应的 pts。我们可以通过 lsof 命令查看 ptmx 打开的文件描述符:

一般来说,当我们通过远程连接执行命令时,进程的标准输入、标准输出和标准错误输出都绑定到伪终端。下面是一个简单的演示程序:

[En]

In general, when we execute a command through a remote connection, the standard input, standard output and standard error output of the process are all bound to the pseudo terminal. Here is a simple demo program:

将此代码保存在文件mydemo.c中,然后执行以下命令来编译和执行程序:

[En]

Save this code in the file mydemo.c, and then execute the following command to compile and execute the program:

demo 程序输出了自己进程的 PID,现在另外开一个终端执行 lsof 命令:

您可以看到,进程的0u(标准输入)、1u(标准输出)和2u(标准错误输出)都绑定到伪终端/dev/pt/0。

[En]

You can see that 0u (standard input), 1U (standard output), and 2u (standard error output) of the process are all bound to the pseudo terminal / dev/pts/0.

Original: https://www.cnblogs.com/sparkdev/p/11605804.html
Author: sparkdev
Title: Linux 伪终端(pty)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/7233/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

最近整理资源【免费获取】:   👉 程序员最新必读书单  | 👏 互联网各方向面试题下载 | ✌️计算机核心资源汇总