Linux 伪终端的基本原理 及其在远程登录(SSH,(2)

linux中为什么要提出伪终端这个概念呢?shell等命令行程序不可以直接从显示器和键盘读取数据吗?为了同屏运行多个终端模拟器、并实现远程登录,还真不能让bash直接跨过伪终端这一层。在操作系统的一大思想——虚拟化的指导下,为多个终端模拟器、远程用户分配多个虚拟的终端是有必要的。上图中的shell使用的slave端就是一个虚拟化的终端。master端是模拟用户一端的交互。之所以称为虚拟化的终端,它除了转发数据流外,还要有点终端的样子。

作为终端的伪终端

最为一个虚拟的终端,每一个伪终端里面封装了一个终端驱动,让它能做到这些事情:

为程序提供一些输入输出模式的帮助,比如输入密码时隐藏字符

为用户提供对进程的控制,比如按下Ctrl+C结束前台进程

对,这些就是转发数据之外的控制。

终端的属性:回显控制和行控制

当用户按下一个按键时,字符会出现在屏幕上。这可不是CLI进程写回来的。不信的话可以在终端里运行cat,随便输入些什么按回车。第二行是cat返回来的,第一行正是终端的特性。

终端驱动里存储了一个状态——回显控制:是否将写入master的字符再次送回master的读端(显示器)。默认情况下这个是启用的。在命令行里可以使用stty来更改终端的状态。比如在终端中运行

stty -echo

则会关掉当前终端的回显。这时按下按键,已经没有字符显示出来了。输入ls等命令,能够看到shell正常接收到我们的命令(此时回车并没有显示出来)。这时cat后,盲打一些文字,按下回车后看到只有一条文字了。

Linux 伪终端的基本原理 及其在远程登录(SSH,

除了用户通过命令行方式,CLI的程序还能通过系统调用来设置终端的回显,比如login,sudo等程序就是通过暂时关闭回显来隐藏密码的。具体方式是在slave的文件描述符上调用ioctl函数(参考man tty_ioctl),不过推荐使用更友好的tcsetattr函数。详细设置可查阅man tcsetattr。

另外,终端驱动还提供有行缓冲功能。还是以cat为例:当我们输入文字,在键入回车之前,cat并不能读取到我们输入的字符。这里的cat的行为可以理解为逐字符读写:

while(read(0, &c, 1) > 0) //read from stdin, while not EOF write(1, &c, 1); //write to stdout

是谁阻止cat及时读入字符了呢?其实是终端驱动。它默认开启了一个行缓冲区,这样等程序要调用read系统调用时,先让程序阻塞着(blocked),等用户输入一整行后,才解除阻塞。我们可以使用下列命令将行缓存大小设置为1:

stty min 1 -icanon

这时,运行cat,尝试输入文字。每输入一个字符,能够立即返回一个字符。(把min改为time,还能设置输入字符最长1秒后阻塞)

这些终端的状态属性信息还有很多,比如设置终端的宽度、高度等。具体可以参考man stty。

特殊控制字符

特殊控制字符,是指Ctrl和其他键的组合。如Ctrl+C、Ctrl+Z等等。用户按下这些按键,终端模拟器(键盘)会在master端写入一个字节。规则是:Ctrl+字母得到的字节是(大写)字母的ascii码减去0x40。比如Ctrl+C是0x03,Ctrl+Z是0x1A。参见下表:

Linux 伪终端的基本原理 及其在远程登录(SSH,

驱动收到这些特殊字符,并不会像收到正常字节那样处理。在echo的时候,它返回两个可见字符。比如键入Ctrl+C(0x03),就会回显^和C(0x5E 0x03)两个字符。更重要的是,驱动将会拦截某些控制字符,他们不会被转发给slave端,而是触发作业控制(job control)的规则:向前台进程组发送SIGINT信号。

要想绕过这一机制,我们可以使用stty的一些设置。下面的命令能够同时关闭控制字符的特殊语义、设置行缓冲大小为1:

stty raw

然后,运行cat命令,我们键入的所��字符,包括控制字符Ctrl+C(0x03),都会成功传递给cat,并且被原样返回。(可以试试上下左右、回车键的效果)

实验:利用伪终端实现远程登录

理解伪终端的基本原理后,我们就可以尝试解释telnet和SSH等远程登录的原理了。每次用户通过客户端连接服务端的时候,服务端创建一个伪终端master、slave字符设备对,在slave端运行login程序,将master端的输入输出通过网络传送至客户端。至于客户端,则将从网络收到的信息直接关联到键盘/显示器上。我们将这个过程描述为下图:

Linux 伪终端的基本原理 及其在远程登录(SSH,

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/13436.html