# 35.8. `pty` - 伪终端实用程序

源代码： Lib / pty.py

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

因为伪终端处理高度依赖于平台，所以有代码只为Linux做它。（Linux代码应该在其他平台上工作，但还没有经过测试。）

`pty`模块定义以下函数：

`pty.``fork`()

  叉子。将孩子的控制终端连接到伪终端。返回值是`（pid， fd）`。注意，孩子得到pid 0，而fd是无效。父的返回值是孩子的pid，fd是连接到孩子的控制终端（以及孩子的标准输入和输出）的文件描述器。

`pty.``openpty`()

  打开一个新的伪终端对，使用`os.openpty()`（如果可能）或通用Unix系统的仿真代码。分别为主机和从机端返回一对文件描述器`（主机， 从机）`

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

  产生一个进程，并将其控制终端与当前进程的标准io连接。这通常用于阻挡坚持从控制终端读取的程序。

  函数master_read和stdin_read应为从文件描述器读取的函数。默认值尝试在每次调用时读取1024字节。

  在版本3.4中更改： `spawn()`现在从`os.waitpid()`返回子进程的状态值。

## 35.8.1. Example

以下程序的作用类似于Unix命令脚本（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)