一文带你彻底理解Linux的各种终端类型及概念( 三 )


【一文带你彻底理解Linux的各种终端类型及概念】先看下Linux系统中管终端都叫做什么 。

一文带你彻底理解Linux的各种终端类型及概念

文章插图
 
tty是最令人熟悉的了 , 在Linux中 , /dev/ttyX代表的都是上述的物理终端 , 其中 , /dev/tty1~/dev/tty63代表的是本地终端 , 也就是接到本机的键盘显示器可以操作的终端 。换句话说 , 你往/dev/tty3里写个东西 , 它就会显示在显示器对应的终端 。
为什么会有63个终端这么多呢?毕竟显示器只是一个单独的显示设备 , 键盘往往也只有一个 , 但Linux内核有能力知道现在该干什么 , 所以事实上Linux内核在初始化时会生成63个本地终端 , 通过键盘上的Fn-Alt-FX(X为1,2,3…)可以在这些终端之间切换 , 每切换到一个终端 , 该终端就是当前的焦点终端 , 比如说 , 你按下了Fn-Alt-F4组合键 , 那么此时第4个终端就是焦点终端 , 即/dev/tty4就是焦点终端设备 。
一文带你彻底理解Linux的各种终端类型及概念

文章插图
 
谁是焦点终端会被内核记录为全局变量 , 这样只要有键盘输入 , 就会把输入的字符交给焦点终端 。这里顺便提一下 , 对于串口而言 , 不存在焦点终端的概念 , 谁连了串口就是谁 , 而对于伪终端来讲 , 一般情况下client都是运行在GUI环境 , 对于Windows那是微软的事 , 对于Linux , 则有X系统完成同样的事 , 在此略过 , 继续我们正在说的话题 。
系统中有没有什么变量可以表示焦点终端呢?当然有了 , 那就是/dev/console , 不管你在哪里往/dev/console里写东西 , 这些东西总会出现在系统当前的焦点终端上!
按照以他人为中心 , 我们解释了/dev/console其实就是一个全局变量 , 指代当前的焦点终端 , 如果当前的焦点是/dev/tty4 , 那么/dev/console指的就是/dev/tty4 , 当然这一切都是由内核来维护的 。
那么系统中有没有一个叫做自己的全局变量呢?当然有 , 那就是/dev/tty , 也就是说 , 无论你在哪个终端下工作 , 当你往/dev/tty里写东西的时候 , 它总是会马上出现在你的眼前 。
/dev/tty1~/dev/tty63我们知道了它们是什么 , /dev/tty表示自己 , /dev/console表示焦点终端这些我们也知道了 , 那么串口终端如何表示呢?很简单 , 以ttyS
开头的就是串口连接的终端 , 比如ttyS1 , ttyS2…
最后 , 解释一下伪终端 。其实也很好解释 , 只要你理解TUN/TAP虚拟网卡的原理就行 , 它们如出一辙!类似Telnet , SSH不是没有实际的物理设备吗?简单 , 给它模拟一个不就得了?系统是分层的 , 执行流只管调用接口 , 并不管具体实现 。
模拟一个虚拟的终端设备 , 实现它的write , read等回调即可 。对于VGA连接的显示器而言 , write其实就是将显存刷新 , 而对于伪终端而言 , write其实是想将数据导入到一个用户态的程序中(不然又能去哪里呢?它下面又没有任何物理的东西) , 这简直跟很多VPN的原理非常类似 。为此 , Linux设计出一对虚拟终端设备 , 即/dev/ptmx和/dev/pts/X , 这就跟TUN/TAP网卡的网卡与字符设备之前的对应关系一致 。
简单来讲 , 当有ssh客户端连接后 , sshd会fork一个进程 , 然后在子进程中打开一个叫做/dev/pts/1(或者2,3,4,5…)的设备 , 然后和sshd进程的/dev/ptmx配对 , 这样在ptmx与pts之间就构成了一条管道 , 数据可以顺利被导入到sshd , 然后通过TCP/IP封装发往ssh client所在的机器 。
为了帮助理解上述的文字 , 我特意作图一张 , 希望能解释清楚这些终端之间的关系以及弄明白它们的工作流程 。为了让图画的更加紧凑 , 避免横向网络吧图拉的过长而不好看 , 我这里采用了环形解释法 , 类似Intel早先的Ring1 , Ring2 , Ring3 , 我把最内层视作硬件(比它更里面的还有叫做人的东西) , 中间层视作内核 , 最外层视作软件 。


推荐阅读