探寻TTY的前世今生

univac-9400

用过类Unix系统的朋友,应该对console、terminator、tty、pty、shell这些单词都不陌生,也应该听说过设备文件、Unix一切皆文件等等说法。但是却很少有人能清晰的解释他们的区别和原理(反正在这之前我也是很懵的),这里我们就来好好捋一捋。

console、terminal、tty、pty傻傻分不清楚

历史

要说这些词,我们应该先回顾一下历史,之所以会有这些词背后有一些历史原因。这里我根据我查询到的资料简单的介绍一下。

美国电讯公司的雇员Edward A. Calahan于1867年发明了证券报价机,这是一台由打字机,一对长电缆和一个自动收录机打印机组成的电动机械机器,其目的是长距离实时传播股票的价格。Ticker tape是最早的数字电子通信媒介,通过电报线传输股票价格信息,在1870年至1970年间使用,这就是后来的电传打字机的原型。

TTY的历史要比计算机的出现更早,在计算机出现之前,人们就已经在使用电传打字机(英语:Teleprinter、Teletypewriter,缩写为 TTY)来发送数据。它的工作原理跟前面的证券报价机类似,不过采用了更高级的编码形式,这时候电传打字机和电脑还没有任何关系,因为电脑还没被发明呢。

在我们今天常见的PC出现之前,计算机的形态是与如今的个人电脑截然不同的,我们小学的计算机教材上就提到过的ENIAC是世界上第一台通用电子计算机(更早的计算机要么是机电计算机例如德国的Z3,要么就不是通用计算机例如美国的ABC),它是图灵完全的电子计算机,能够重新编程,解决各种计算问题。这玩意儿的体积非常庞大,占地167平米,重达27吨。它采用IBM的卡片阅读器用于输入,打卡器用于输出。打孔卡的技术最早出现在1801年,前面提到的Ticker tape和TTY实际上也采用了该技术。因为当时的计算机是给科学家用的,也不需要什么远程连接,所以输入输出设备的选择上并没有过多的考虑。这玩意儿用起来的场面相当壮观:

不过科学家也忍受不了这么反人类的输入输出方式,于是就想把电传打字机和计算机相结合。于是第一台支持“键盘”输入的计算机PDP1诞生了,自此以后, 计算机的输入设备和输出设备有了根本改变:

再后来电脑看起来像是一大堆具备一些奇怪按钮和指示灯的,衣柜一般大小的柜子。这就是传说中的“小型机”(相较于大型机,这确实算小的了),这些柜子里有的装的是处理单元,相当于今天的CPU,其中一个装着穿孔读卡器作为输入设备,其余的装着磁带、硬盘、打印机等等。就像这样子(下图是一套Univac 9400计算机):

univac-9400

这张图右侧那些奇怪的按钮和一堆指示灯,就是所谓的console,它是早期计算机主机的一部分,通常和CPU共享一个机柜。在console左侧那个面前有个椅子的大桌子上的设备,就是传说中的Teletypewriter,当时的TTY指的就是这样的设备。下面还有一张图,展示的是Teletype Model 33 ASR (1963)

随着技术的进步,电传打字机终端被视频显示终端所取代。计算机终端是用于将数据输入计算机或计算系统并从计算机或计算系统显示数据的电子或机电硬件设备,简单的说就是输出不再是打印在纸上的了,直接显示在屏幕上。于是操作电脑的方式变成了下图(A DEC VT52 video terminal connected to a PDP 11/55 computer.)这样,你可以坐在终端面前实现输入输出:

A DEC VT52 video terminal connected to a PDP 11/55 computer.

console与Terminal的区别:

console and term

下面是一张DEC VT100 terminal的照片,看上去已经很像现在的个人电脑了,不过千万别误会,终端实际上是不具备计算能力的,它只是计算机的输入输出设备而已,相当于只有键盘+显示器+网线,其他的CPU、内存、硬盘等都在那些柜子一样大的计算机上:

它的工作原理大致是这样的:

1
2
3
4
5
                                                                      +----------+ 
+----------+ +-------+ Physical Line +-------+ +------+ | |
| Terminal |<->| Modem |<--------------------->| Modem |<->| UART |<->| Computer |
+----------+ +-------+ +-------+ +------+ | |
+----------+
  • 左边的Terminal就是各种各样的teletype
  • 物理线路两边用上了Modem,通过网络连接到远端
  • UART可以理解为将teletype的信号转换成计算机能识别的信号的设备

我们可以简单总结一下以前的console、terminator、tty了:

  • tty 和 terminal 都是输入输出的外设,不过terminal输出到显示器,tty输出到纸上。现代计算机上这两个词可以认为是同义词。
  • console是集成在计算机机柜上的物理操作面板
  • 它们都属于硬件,另外,它们都已经被淘汰了

终端工作原理

上面只介绍了硬件,下面我们介绍一下它们是如何工作的。在Unix术语中,tty是一种特殊类型的设备文件,它实现了除读写之外的许多附加命令,例如控制换行、信号处理以及会话管理等。说到这里就顺便讲一下所谓的设备文件。

Unix系统采用了一种抽象的方法,将设备抽象成文件。我们先考虑一下一个普通的文件:包含数据,具备属性,通过目录中的名字被标示。可以从文件中读取数据,也可以将数据写入文件。想象一下将这种方法应用到设备上。一个带有键盘和显示器的终端也可以和文件类似,键盘输入的数据能被程序所读取,程序也能将数据写入终端显示在屏幕上。

再顺便简单说一下内核,我们知道Unix是一个多用户系统,可能有多个用户运行多个程序,访问多个设备。这时候就可能会出现一些混乱的情况,而内核的作用就是让所有的资源访问都被集中管理,任何用户要访问系统的资源都要经过内核。我们所谓的操作系统实际上其核心就是内核,可以看作是一个特殊的程序,内核运行的空间称之为内核空间,其余的程序则运行在用户空间。

通过上面的简单介绍,我们应该知道了终端要和程序交互也要经过Kernel,操作系统内部为了支持这些各式各样的终端,就设计了这样的子系统:

结合上面的硬件一起看就是这样:

如今

现在在Unix系统中,tty的意思跟硬件没啥关系了。如今我们所谓的终端、tty等,实际上是软件和系统层面上对以上设备的模拟,上面讨论的这些概念都已经过时了,但是它们的软件设计思想缺沿用至今。区别在于我们不再需要那些硬件,而是通过软件模拟,每台电脑都可以成为多个终端。

现在让我们来看在一个典型的桌面系统中linux的控制台子系统是如何工作的:

如果我们启动一台Linux操作系统的电脑,直接在键盘上按下ctrl+alt+FN切换的tty就是这个玩意儿。那pty又是什么呢?

上图中的Terminal emulator是在内核中实现的,现在我们把它挪出来,如此一来你可以在一个显示器内控制多个终端,xterm就是这样工作的,更为常见的Windows平台上的Xshell和macOS上的iTerm2也是这样的东西。

伪终端(Pseudo Terminal)是终端的发展,为满足现在需求(比如网络登陆、xwindow窗口的管理)。它是成对出现的逻辑终端设备(即master和slave设备, 对master的操作会反映到slave上)。它多用于模拟终端程序,是远程登陆(telnet、ssh、xterm等)后创建的控制台设备。

上图中描述了我们的本地程序跟远端的程序通讯的流程,不过我们无法将数据直接通过网络发送给面向终端的程序(我们接触到的命令行程序就是面向终端的程序),它期望的是一个终端进行通信。于是就有了pty的设计:

面向终端程序的标准输入、输出及错误输出都连接到未终端的从设备上,它也是程序的控制终端。驱动程序则作为用户的代理,提供面向终端程序程序的输入并读取程序的输出。简单的说就是pty是成对出现的逻辑终端设备,slave端连接具体的面向终端程序,而master负责分配和管理slave,同时也是代理,与驱动程序交换输入输出。下面我们以ssh为例介绍一下具体的步骤

  1. 位于终端的用户通过终端模拟器使用ssh客户端
  2. ssh程序经过网络连接到sshd服务
  3. sshd服务与pty master进行数据交换
  4. ptmx收到数据后,根据fd找到对应的pts(该对应关系由ptmx自动维护),将数据包转发给对应的pts
  5. pts收到数据包后,检查绑定到自己上面的当前前端进程组,将数据包发给该进程组的leader,这里就是shell程序
  6. shell通过write函数将结果写入pts
  7. pts将结果转发给ptmx
  8. ptmx根据pts找到对应的fd,往该fd写入结果
  9. sshd收到该fd的结果后,找到对应的session,然后将结果发给对应的ssh客户端

总结

现在可以总结一下console、terminal、tty和pty了:

  • 过去:
    • console是上古时期的产物,是机柜上的控制按钮和指示灯,它的指令优先级高于terminal
    • tty 和 terminal 都是输入输出的外设,不过terminal输出到显示器,tty输出到纸上。现代计算机上这两个词可以认为是同义词。
  • 如今:
    • 现代计算机中terminal和tty算是同义词,没有区别
    • 现在常说的终端,实际上是终端模拟器
    • tty和pty的区别在于tty的终端模拟是在内核中完成的。你可以简单的理解为直接连接电脑显示器和键盘看到的是tty,远程登录的则是pty

参考文档

坚持原创技术分享,您的支持将鼓励我继续创作!