提问
以下四个快捷键中,哪些是由PTY实现的,哪些是由Shell实现的?
- Ctrl-E
- Ctrl-W
- Ctrl-B
- ↑(上一个命令)
TTY,PTY,Terminal,Shell都是啥?

我们经常使用的”黑框”有很多关联的名词,比如:
- Terminal(终端)
- Console
- TTY
- PTY
- Shell
这些都是指我们使用的那个”黑框”吗?
历史溯源
要理解这些名词概念,必须要先回首历史.
其实早在计算机出现之前,就有了类似的输入设备,就是电报机.
休斯印刷电报机就是一个纯机械设备.起源1855年.
1901年,出现了电传打字机.Teletype, 也就是TTY.使用的QWERTY键盘,也是现代键盘键位的起源.
到了Unix时代(1970),电传打字机作为计算机的主要输入设备.
这里需要补充下,早期并没有“个人”电脑,计算机是稀缺资源,是共用的,使用者需要用一个设备接入计算机。这个设备位于整个系统的边缘,所以叫终端-Terminal。
图中Ken Thompson大佬正在操作的就是TTY.而机柜上的按钮窗口就是console,也是输入设备之一.不过当时输入输出还是显示在纸上.
随后不久就出现了电子显示器,比较有名的就是VT100.是第一个支持ANSI字符集的终端.是的,终端这个词用来表述这种电子显示器+键盘的组合设备比较合适.我个人理解TTY也是一种终端,终端是一个概念,不像TTY是一种具体设备.
截止到VT100时代,终端还是只是一个“无脑”的输入输出设备。终端和计算机还是物理上完全分离的结构,两者之间通信链路如下:
图中左侧Hardware部分可以理解为VT100设备,其与计算机之间使用UART通信。
Line discipline是行规程序,负责缓存字符、回显、擦除、信号翻译等工作。
TTY driver 负责跟踪前台用户进程组id,行列显示参数,发送某些信号等工作,我们运行ls命令,其实也是由TTY driver执行的。
个人感觉这些工作完全没必要让内核处理,但考虑当时的时代背景,unix是宏内核,TTY这些功能又是每个计算机必备的,所以放入内核中也很合适。
随后来到个人电脑时代,比较有代表性的就是IBM 3277 Model 2,1971年发布。
图中的设备不再是简单的输入输出设备了,而是一台完整的计算机,终端和计算机合二为一,也是我们大多数人一开始接触硬件模型。
既然两者合二为一了,那么原来终端的少量的软件功能也被计算机(内核)兼并了。虽然硬件层面终端和计算机是一体的,但软件层面还是有终端的概念的,下图中终端的软件功能是由操作系统内核模拟的。对比VT100,终端只剩下了键盘和显示器。
又过了10来年,我们来到了伟大的GUI时代。这时代的代表作就是X window system和苹果第一台个人电脑Macintosh 128K。
带有图形界面的电脑开机后,显示器不再被“黑框”霸占,而是显示友好的“窗口界面“。
那么如何在图形窗口之上使用之前的终端呢?
答案是图形终端模拟器, 为什么是“模拟器”呢?其实和内核模拟的tty一样,没有真实的“终端”硬件设备,我们所打开的“黑框”窗口是由软件模拟出来的终端,所以叫模拟器。
此时的软件架构又有所不同了,以xterm为例,xterm是用户级进程,也就是我们在图形界面打开的“黑框”,内核提供了PTY Master和PTY Slave这样一对接口,数据流在两者之间来回传送,其封装了传统终端的功能,让xterm专注于实现GUI部分。
随着网络的发展,我们可以在一台计算机上利用ssh登录到另一台远端机器上。数据流转更加复杂了。
首先客户端需要用xterm模拟一个本地终端,本地PYT-Slave使用bash运行ssh和远端ssh server建立连接。
远端ssh server也需要打开一对PTY设备,使用PTY-Slave执行client发送过来的命令。
至此我们看到,TTY指的是具体设备:电传打字机,是硬件。
PTY指的是虚拟电传打字机,是软件。
Terminal在不同时期所指的是不同的目标,早期指的是TTY,后来指的是PTY,所以Terminal并没有准确定义。
Console早起指的是大型计算机的控制面板,而现代和Terminal的含义是一样的。
Shell又是什么?
其实从前述的图中可以看出,shell仅仅是一个普通的用户级程序,用于解析执行用户输入的命令。
比如我们常用的bash,就静静地躺在/bin
目录下。
一个普通的程序,为什么被称为Shell呢?来看看下面这张图。
最内层是操作系统内核,其管理着计算机各种硬件资源,操作系统提供一些列的系统调用供用户空间程序调用。
我们想方便地指挥操作系统,不能每次都使用编程调用系统调用的方式,这样太麻烦。所以就需要有一类程序,提供更人性化的方式让我们跟计算机交互,这类程序其中之一就是shell,让我们可以输入各种指令去操作计算机。
这类程序就像操作系统内核外面的一层“壳”一样。所以被统称为Shell。
总结
现在再来看看题目中这几个名词,其意义就比价清晰了。
- Terminal 早期指的是用户侧的输入输出设备,现代计算机已经没有这种独立设备,更多指的是图形界面下的终端模拟器。
- Console 早期指的是计算机的物理操作面板。现代计算机已经没有这个面板,更多指的是图形界面下的终端模拟器。
- TTY 早期指的是电传打字机。现代已经消失,更多指的是内核中的TTY Driver。
- PTY 对内核来说,指的是内核提供的终端接口。对应用户来说更多指的是图形界面下的终端模拟器。
- Shell 指的是一种特殊的应用程序,给人类和计算机之间架起一座友好沟通的桥梁。当然这个桥梁不止Shell一种,我们现在每天使用的图形窗口界面对普通用户来说更友好。
参考
- https://www.linusakesson.net/programming/tty/
- https://dev.to/napicella/linux-terminals-tty-pty-and-shell-192e
- https://dev.to/dwgillies/comment/p49i
- https://www.zhihu.com/question/21711307
- https://nullprogram.com/blog/2012/04/23/
- https://mp.weixin.qq.com/s/MNJ3DrXBkzgwxE8yTBCRBQ
- https://github.com/rprichard/winpty
- https://en.wikipedia.org/ Pseudoterminal, Unix, Ken Thompson, Dennis Ritchie, VT100, ANSI escape code, IBM 3270, Apple II ,Macintosh
- The Linux Programming Interface: Chapter 62, 64
- Advanced Programming in the UNIX® Environment, Third Edition: Chapter 18, 19