pty ---伪终端实用程序

源代码: Lib/pty.py


这个 pty 模块定义了处理伪终端概念的操作:启动另一个进程,并能够以编程方式对其控制终端进行写入和读取。

因为伪终端处理高度依赖于平台,所以只有Linux才有这样做的代码。(Linux代码应该在其他平台上工作,但还没有经过测试。)

这个 pty 模块定义以下功能:

pty.fork()

叉子。将子项的控制终端连接到一个伪终端。返回值为 (pid, fd) . 注意,子项 pid 0,以及 fd无效 . 父级的返回值是 pid 子项的,以及 fd 是一个文件描述符,连接到子系统的控制终端(以及子系统的标准输入和输出)。

pty.openpty()

打开一个新的伪终端对,使用 os.openpty() 如果可能,或通用UNIX系统的仿真代码。返回一对文件描述符 (master, slave) ,分别用于主端和从端。

pty.spawn(argv[, master_read[, stdin_read]])

生成一个进程,并将其控制终端连接到当前进程的标准IO。这通常用于阻止坚持从控制终端读取的程序。预计在PTY后面产生的进程最终将终止,当它终止时 产卵 会回来的。

功能 master_readstdin_read 传递一个他们应该从中读取的文件描述符,并且他们应该始终返回一个字节字符串。为了强制在子进程退出之前返回 OSError 应该被抛出。

每次调用函数时,这两个函数的默认实现将读取并返回最多1024个字节。这个 master_read 将回调传递给伪终端的主文件描述符以从子进程中读取输出,并且 stdin_read 传递文件描述符0以从父进程的标准输入中读取。

从任一回调返回空字节字符串都被解释为文件结束(EOF)条件,之后将不会调用该回调。如果 stdin_read 控制终端的信号EOF不能再与父进程或子进程通信。除非子进程在没有任何输入的情况下退出, 产卵 然后将永远循环。如果 master_read 为相同的行为结果(至少在Linux上)发送EOF信号。

如果两个回调都发出EOF信号,则 产卵 可能永远不会回来,除非 选择 传递三个空列表时在平台上引发错误。这是一个错误,记录在 issue 26228 .

从返回退出状态值 os.waitpid() 在子进程上。

waitstatus_to_exitcode() 可用于将退出状态转换为退出代码。

提出一个 auditing event pty.spawn 带着论证 argv .

在 3.4 版更改: spawn() 现在返回状态值 os.waitpid() 在子进程上。

例子

以下程序的作用类似于unix命令 script(1) ,使用一个伪终端在“typescript”中记录终端会话的所有输入和输出。::

import argparse
import os
import pty
import sys
import time

parser = argparse.ArgumentParser()
parser.add_argument('-a', dest='append', action='store_true')
parser.add_argument('-p', dest='use_python', action='store_true')
parser.add_argument('filename', nargs='?', default='typescript')
options = parser.parse_args()

shell = sys.executable if options.use_python else os.environ.get('SHELL', 'sh')
filename = options.filename
mode = 'ab' if options.append else 'wb'

with open(filename, mode) as script:
    def read(fd):
        data = os.read(fd, 1024)
        script.write(data)
        return data

    print('Script started, file is', filename)
    script.write(('Script started on %s\n' % time.asctime()).encode())

    pty.spawn(shell, read)

    script.write(('Script done on %s\n' % time.asctime()).encode())
    print('Script done, file is', filename)