下面由
linux系统教程
栏目给大家介绍Linux TTY/PTS及其作用区别,希望对需要的朋友有所帮助!
Linux TTY/PTS概述
当我们在键盘上敲下一个字母的时候,到底是怎么发送到相应的进程的呢?我们通过ps、who等命令看到的类似tty1、pts/0这样的输出,它们的作用和区别是什么呢?
TTY历史
支持多任务的计算机出现之前
在计算机出来以前,人们就已经在使用一种叫teletype的设备,用来相互之间传递信息,看起来像下面这样:
+----------+ Physical Line +----------+ | teletype || teletype | +----------+ +----------+
两个teletype之间用线连接起来,线两端可能也有类似于调制解调器之类的设备(这里将它们忽略),在一端的teletype上敲键盘时,相应的数据会发送到另一端的teletype,具体功能是干什么的,我也不太了解。(我脑袋里面想到画面是在一端敲字,另一端打印出来)
这些都是老古董了,完全没接触过,所以只能简单的推测。
支持多任务的计算机出现之后
等到计算机支持多任务后,人们想到把这些teletype连到计算机上,作为计算机的终端,从而可以操作计算机。
使用teletype的主要原因有两个(个人见解):
现实中已经存在了大量不同厂商的teletype,可以充分利用现有资源
teletype的相关网络已经比较成熟,连起来方便
于是连接就发展成这样:
+----------+ +----------+ +-------+ Physical Line +-------+ +------+ | | | Terminal || Modem || Modem || UART || Computer | +----------+ +-------+ +-------+ +------+ | | +----------+
左边的Terminal就是各种各样的teletype
物理线路两边用上了Modem,就是我们常说的“猫”,那是因为后来网络已经慢慢的变发达了,大家可以共享连接了。(大概推测,可能不对)
UART可以理解为将teletype的信号转换成计算机能识别的信号的设备
内核TTY子系统
计算机为了支持这些teletype,于是设计了名字叫做TTY的子系统,内部结构如下:
+-----------------------------------------------+ | Kernel | | +--------+ | | +--------+ +------------+ | | | +----------------+ | | UART | | Line | | TTY || User process A | | || || | | +----------------+ | | driver | | discipline | | driver || User process B | | +--------+ +------------+ | | | +----------------+ | +--------+ | | | +-----------------------------------------------+
UART driver对接外面的UART设备
Line discipline主要是对输入和输出做一些处理,可以理解它是TTY driver的一部分
TTY driver用来处理各种终端设备
用户空间的进程通过TTY driver来和终端打交道
为了简单起见,后面的介绍中不再单独列出UART driver和Line discipline,可以认为它们是TTY driver的一部分
TTY设备
对于每一个终端,TTY driver都会创建一个TTY设备与它对应,如果有多个终端连接过来,那么看起来就是这个样子的:
+----------------+ | TTY Driver | | | | +-------+ | +----------------+ +------------+ | | || User process A | | Terminal A || ttyS0 | | +----------------+ +------------+ | | || User process B | | +-------+ | +----------------+ | | | +-------+ | +----------------+ +------------+ | | || User process C | | Terminal B || ttyS1 | | +----------------+ +------------+ | | || User process D | | +-------+ | +----------------+ | | +----------------+
当驱动收到一个终端的连接时,就会根据终端的型号和参数创建相应的tty设备(上图中设备名称叫ttyS0是因为大部分终端的连接都是串行连接),由于每个终端可能都不一样,有自己的特殊命令和使用习惯,于是每个tty设备的配置可能都不一样。比如按delete键的时候,有些可能是要删前面的字符,而有些可能是删后面的,如果没配置对,就会导致某些按键不是自己想要的行为,这也是我们在使用模拟终端时,如果默认的配置跟我们的习惯不符,需要做一些个性化配置的原因。
后来随着计算机的不断发展,teletype这些设备逐渐消失,我们不再需要专门的终端设备了,每个机器都有自己的键盘和显示器,每台机器都可以是其它机器的终端,远程的操作通过ssh来实现,但是内核TTY驱动这一架构没有发生变化,我们想要和系统中的进程进行I/O交互,还是需要通过TTY设备,于是出现了各种终端模拟软件,并且模拟的也是常见的几种终端,如VT100、VT220、XTerm等。
可以通过命令
toe -a
列出系统支持的所有终端类型
可以通过命令infocmp来比较两个终端的区别,比如
infocmp vt100 vt220
将会输出vt100和vt220的区别。
程序如何和TTY打交道
在讨论TTY设备是如何被创建及配置之前,我们先来看看TTY是如何被进程使用的:
#先用tty命令看看当前bash关联到了哪个tty dev@debian:~$ tty /dev/pts/1 #看tty都被哪些进程打开了 dev@debian:~$ lsof /dev/pts/1 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 907 dev 0u CHR 136,1 0t0 4 /dev/pts/1 bash 907 dev 1u CHR 136,1 0t0 4 /dev/pts/1 bash 907 dev 2u CHR 136,1 0t0 4 /dev/pts/1 bash 907 dev 255u CHR 136,1 0t0 4 /dev/pts/1 lsof 1118 dev 0u CHR 136,1 0t0 4 /dev/pts/1 lsof 1118 dev 1u CHR 136,1 0t0 4 /dev/pts/1 lsof 1118 dev 2u CHR 136,1 0t0 4 /dev/pts/1 #往tty里面直接写数据跟写标准输出是一样的效果 dev@dev:~$ echo aaa > /dev/pts/2 aaa
pts也是tty设备,它们的关系后面会介绍到
通过上面的lsof可以看出,当前运行的bash和lsof进程的stdin(0u)、stdout(1u)、stderr(2u)都绑定到了这个TTY上。
下面是tty和进程以及I/O设备交互的结构图:
Input +--------------------------+ R/W +------+ ----------->| || bash | | pts/1 | +------+ | | +--------+ | +----------------+ +----------+ | | Terminal Emulator || tty2 || User processes | | Monitor || | +----------+ | Terminal | | Monitor || | +----------+ | Terminal |--------------------------+ | Monitor || | +----------+ | Terminal | | Monitor || tmux client | | +--------+ +-------+ | +-------+ +-------------+ | | | | ↑ | +--------+ +-------+ | +-------+ | | | ptmx || pts/2 || shell | | | +--------+ +-------+ | +-------+ | | ↑ | Kernel | ↑ | +-----|---|-------------------+ | | | | | | |w/r| +---------------------------+ | | | | fork | | ↓ | | +-------------+ | | | | | tmux server |
还没有评论,来说两句吧...