pty — 伪终端实用程序 — Python 文档
pty — 伪终端实用程序
源代码: :source:`Lib/pty.py`
pty 模块定义了处理伪终端概念的操作:启动另一个进程并能够以编程方式从其控制终端写入和读取。
伪终端处理高度依赖于平台。 这段代码主要在 Linux、FreeBSD 和 macOS 上测试(它应该可以在其他 POSIX 平台上运行,但没有经过彻底测试)。
pty 模块定义了以下函数:
- pty.fork()
- 叉子。 将孩子的控制终端连接到伪终端。 返回值为
(pid, fd)
。 注意子进程得到 pid 0,而 fd 是 invalid。 父的返回值是子的 pid,而 fd 是连接到子的控制终端(也连接到子的标准输入和输出)的文件描述符。
- pty.openpty()
- 打开一个新的伪终端对,如果可能,使用 os.openpty(),或通用 Unix 系统的仿真代码。 分别返回一对文件描述符
(master, slave)
,分别用于主从端。
- pty.spawn(argv[, master_read[, stdin_read]])
生成一个进程,并将其控制终端与当前进程的标准 io 连接。 这通常用于阻止坚持从控制终端读取的程序。 预计在 pty 后面生成的进程最终将终止,并且当它终止时 spawn 将返回。
循环将当前进程的 STDIN 复制到子进程,并将从子进程接收到的数据复制到当前进程的 STDOUT。 如果当前进程的 STDIN 关闭,则不会向子进程发出信号。
函数 master_read 和 stdin_read 被传递一个文件描述符,它们应该从中读取,并且它们应该始终返回一个字节字符串。 为了在子进程退出之前强制 spawn 返回,应该返回一个空字节数组以表示文件结束。
每次调用该函数时,这两个函数的默认实现都将读取并返回最多 1024 个字节。 master_read 回调通过伪终端的主文件描述符从子进程读取输出,stdin_read 被传递文件描述符 0,从父进程的标准输入读取。
从任一回调返回空字节字符串被解释为文件结束 (EOF) 条件,之后将不会调用该回调。 如果 stdin_read 发出 EOF 信号,则控制终端无法再与父进程或子进程通信。 除非子进程在没有任何输入的情况下退出,否则 spawn 将永远循环。 如果 master_read 发出信号 EOF 相同的行为结果(至少在 linux 上)。
从子进程的 os.waitpid() 返回退出状态值。
waitstatus_to_exitcode()
可用于将退出状态转换为退出代码。在 3.4 版更改: spawn() 现在从子进程的 os.waitpid() 返回状态值。
例子
以下程序的行为类似于 Unix 命令 script(1),使用伪终端将终端会话的所有输入和输出记录在“打字稿”中。
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)