Linux 学习笔记:控制台,终端,tty
整理一下关于下面这些概念的学习:
- 终端(terminal)
- 控制台(console)
- 电传打字机 tty(teletype)
这些概念在早期是有明确的定义的,但是随着计算机的发展,它们的物理实体逐渐消失,各种概念主要靠计算机软件模拟,它们之间的区别变得模糊难以理解,因此学习整理一下,以Linux系统为主。
TODO
- shell
控制台与终端
早期的计算机是一套巨大的机器,就像工厂的大型机器一样,如此的庞然大物必然需要一个专门的操作台, 用于陈列各种仪表盘、指示灯、按钮、电线,专业操作人员通过这个操作台控制计算机的启动、运行、停止,结果也会实时反馈到操作台,这个操作台就叫“控制台”(console)。
控制台是附着在机器上的设备,可以实现对计算机的完全操控,但是主要是用来管理计算机的。 对于多用户操作系统(特别是UNIX),控制台并不方便给用户提供计算服务。 因此自然产生了终端(terminal)的硬件概念:每个用户通过终端设备与主机远程连接(还不是现代意义上的基于互联网的远程连接),管理员给每个用户分配一个账户,用户“登录”到系统获得计算机使用权。在这个阶段,计算机通常只有一个控制台,属于基本设备中的一部分,但是可以连接多个终端,属于附加设备。
按照计算机组成划分,终端设备是一个IO外设:将用户的指令输入到主机,将主机的返回结果输出给用户,仅此而已。
例如下图中,左侧的操作面板就是控制台,右侧的电传打字机就是终端。
在早期,因为价格原因,主要使用电传打字机(teletypewriter)作为终端设备。 电传打字机只是打字机的改进版,在打印的同时通过线缆与计算机进行通信,实际使用上很不方便:
- 用户输入的字符流像打字机一样是删不掉的,而且用户输入什么就会立刻传给主机;
- 主机输出的字符流通过打印在纸上来显示。(输入的字符流好像也会打印在纸上)
从1970年代末期开始,电子视频终端(video terminal)开始取代电传打字机成为主流的终端设备(硬件就是键盘+显示器), 它的操作比点传打字机更加友好:
- 用户的输入和主机的输出都通过电子显示屏展示;
- 带有缓存和删除功能,用户在传给主机之前可以修改输入的信息。
1978年Digital公司生产的VT100时至今日仍然是(模拟)终端的事实标准。
随着个人计算机的普及,在硬件角度上的控制台与终端的概念已经逐渐模糊。 在现代,个人计算机上的键盘与显示器既可以认为是控制台的一部分,也可以认为是终端的一部分: 当你在管理系统时,它们是控制台;当你在做一般的工作时,它们就是终端。我们自己既是系统管理员,也是一般用户。
TTY
Linux 内核中有三个模块共同支持(早期的)终端设备:UART驱动、终端行规程(terminal line discipline)、TTY驱动。
物理终端通过电缆连接到计算机上的 UART(通用异步接收器和发射器),操作系统中有一个 UART 驱动程序用于管理字节流的物理传输。
Linux内核中的 Line discipline(行规程)提供一个编辑缓冲区和一些基本的编辑命令(退格,清除单个单词,清除行,重新打印),主要用来支持用户在输入时的特殊行为(比如输错了,需要退格)。 行规程作用类似于过滤器,比如将按键Ctrl-C、Ctrl-Z等特殊字符解释成相关信号发给前台进程,并不让应用程序读到, 真正可读写的字符才会进一步传递给应用程序或UART驱动。
TTY 驱动用来进行会话管理,与应用程序交互,并且处理各种终端设备。
在 Linux 下所有的设备都是文件,它们三个模块通常被放在一起统称为 "TTY 设备"。 从宏观的角度来说,Linux 内核中的 TTY 一侧对接的是终端设备,另一侧对接的是应用程序,负责在它们之间的字符流中转:
- 维护输入和输出两个字符流队列;
- 终端按键输入的字符流(经行规程处理后)送到输入队列;
- 应用程序通过
tty_read
函数发起读操作,按先入先出原则在队列中读到字符; - 应用程序通过
tty_write
函数发起写操作,输出的字符流(经行规程处理后)送到输出队列; - 驱动程序按先入先出原则将输出队列的字符在终端上显示出来。
如果终端配置成回显(Echo)模式,那么输入队列中字符被送给应用程序的同时也会送到输出队列,此时用户在终端的按键不仅被应用程序读到,同时也在终端回显。