伪终端概述

伪终端就是指,一个应用程序看上去像一个终端,但事实上它并不是个真正的终端。下图显示了使用伪终端时相关进程的典型安排。
[img]http://dl2.iteye.com/upload/attachment/0129/9523/81165c3d-0144-3e08-bb9d-dc8a16b4ccc9.png[/img]
图中的关键点如下。
1、通常,一个进程打开伪终端主设备,然后调用 fork。子进程建立一个新的会话,打开一个相应的伪终端从设备,并将其文件描述符复制到标准输入、标准输出和标准错误,然后调用 exec。伪终端从设备成为子进程的控制终端。
2、对于伪终端从设备上的用户进程来说,其标准输入、标准输出和标准错误都是终端设备。用户进程可以通过这些描述符来处理类似 tcgetattr 等的终端 I/O 函数。但因为伪终端从设备不是真正的终端设备,所以无意义的函数调用(如改变波特率、发送中断符、设置奇偶校验等)将被忽略。
3、任何写到伪终端主设备的都会作为从设备的输入,反之亦然。事实上,所有从设备端的输入都来自于伪终端主设备上的用户进程。这类似于一个双向管道,只是从设备上的终端行规程(见[url=http://aisxyz.iteye.com/admin/blogs/2422412]终端 I/O 综述[/url])使之拥有普通管道没有的其他处理能力。
下面来看看伪终端的某些典型用途。为了简化图示,下面各图中不再画出上图中的“读函数和写函数”,同时使用缩写“PTY”来表示伪终端。
一、网络登录服务器
伪终端可用于构造提供网络登录的服务器。典型的例子是 telnetd 和 rlogind 服务器。一旦登录 shell 运行在远端主机上,即可得到类似下图中所示 rlogind 服务器的进程安排。
[img]http://dl2.iteye.com/upload/attachment/0129/9525/4eb79da8-7a91-3b28-840d-78e632f68d44.png[/img]
图中在 rlogind 服务器和登录 shell 之间有两个 exec 调用,这是因为 login 程序通常是在两个 exec 之间检验用户是否合法。另一个关键点是,驱动 PTY 主设备的进程通常同时在读写另一个 I/O 流,图中的另一个 I/O 流是 TCP/IP 框。这表示该进程必然使用了某种形式的诸如 select 或 poll 这样的 I/O 多路转接,或者被分成两个进程或线程。
二、窗口系统终端模拟
窗口系统通常提供一个终端模拟器,它作为 shell 和窗口管理器之间的媒介。每个 shell 在自己的窗口中执行。这种情况的进程安排如下图所示。
[img]http://dl2.iteye.com/upload/attachment/0129/9744/e157c658-4a08-3041-9549-f2f0d3c7f4bd.png[/img]
shell 将自己的标准输入、标准输出、标准错误连接到 PTY 的从设备端。终端模拟器程序打开 PTY 的主设备,它除了作为窗口子系统的接口,还要负责模拟一种特殊的终端。这意味着它需要根据它所模拟的设备类型来响应返回码。这些码列在 termcap 和 terminfo 数据库中(见[url=http://aisxyz.iteye.com/admin/blogs/2423871]终端窗口大小和 termcap[/url])。
当用户改变终端模拟器窗口的大小时,窗口管理器会通知终端模拟器。终端模拟器在 PTY 的主设备端发出 TIOCSWINSZ ioctl 命令来设置从设备的窗口大小。如果新的窗口大小和当前的不同,内核会发送一个 SIGWINCH 信号给前台 PTY 从设备的进程组。如果应用程序在窗口大小改变时需要重绘屏幕,它就会捕捉该信号,然后发出 TIOCSWINSZ ioctl 命令来获得新的屏幕尺寸并重绘屏幕。
三、script 程序
script(1)程序会将终端会话期间的所有输入和输出信息复制到一个文件中。为此,它将自己置于终端和一个新调用的登录 shell 之间。script 程序通常是从登录 shell 启动的,该 shell 还要等待 script 程序的终止。下图描述了和 script 程序有关的交互。
[img]http://dl2.iteye.com/upload/attachment/0129/9746/9262e47e-6da7-318a-b101-2ff6dad44363.png[/img]
script 程序运行时,位于 PTY 从设备上的终端行规程的所有输出都将复制到脚本文件中(通常称为 typescript)。注意,由于击键通常由该行规程模块回显,所以该脚本文件中也包括了输入的内容(不过键入的口令一般不回显,因此通常不会包含口令)。
四、expect 程序
伪终端可以用来在非交互模式中驱动交互式程序的运行。expect 程序就可以通过一个脚本来驱动交互式程序,并且它还提供了一种编程语言用于检查运行程序的输出,以确定用什么作为输入发送给该程序。当一个源自脚本的交互式的程序正在运行时,不能仅仅是将脚本中的所有内容复制到程序中去,或者将程序的输出送至脚本,而是必须要向程序发送某个输入,检查它的输出,并决定下一步发送给程序的内容。
五、观看长时间运行程序的输出
标准 shell 可以将一个需要长时间运行的程序放到后台运行,但如果该程序的标准输出重定向到一个文件,并且它产生的输出又不多,那么就不能方便地监控程序的进展,因为标准 I/O 库将完全缓冲它的标准输出,导致看到的只是标准 I/O 库函数写到输出文件中的成块输出。
如果有源程序,则可以加入 fflush 调用强制标准 I/O 缓冲区在某些节点冲洗或者使用
setvbuf 函数([url=http://aisxyz.iteye.com/admin/blogs/2387136]流和缓冲[/url])把缓冲模式改成行缓冲。而如果没有源程序,则可以考虑编写一个程序 pty 来运行该程序,这个 pty 程序可以让标准 I/O 库认为标准输出是终端,以此达到设置行缓冲的目的。下图显示的就是利用伪终端运行一个缓慢输出的程序 slowout 的进程安排情况。其中用虚线表示从登录 shell 到 pty 进程的 fork/exec 箭头是为了强调 pty 进程是作为后台任务运行的。
[img]http://dl2.iteye.com/upload/attachment/0129/9748/525eba52-b006-3abf-8d48-89a25bdcb2ad.png[/img]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值