欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

伪终端概述

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