Документация Python неофициальный перевод
Содержание страницы

35.8. pty – Утилиты псевдо-терминалаpty – Pseudo-terminal utilities

Модуль pty определяет операции для работы с псевдо-терминалом: запуск другого процесса и программную запись и чтение его управляющего терминала.

Поскольку работа с псевдотерминалами сильно зависит от платформы, код для этого реализован только для Linux. (Предполагается, что код для Linux будет работать и на других платформах, но это ещё не проверено.)

Модуль pty определяет следующие функции:

pty.fork()

Fork. Подключает управляющий терминал дочернего процесса к псевдо-терминалу. Возвращаемое значение – (pid, fd). Обратите внимание, что дочерний процесс получает pid 0, а fd является недействительным. Родительский процесс получает pid дочернего процесса, а fd – это файловый дескриптор, подключённый к управляющему терминалу дочернего процесса (а также к его стандартному вводу и выводу).

pty.openpty()

Открывает новую пару псевдо-терминалов, используя os.openpty(), если это возможно, или код эмуляции для обычных Unix-систем. Возвращает пару файловых дескрипторов (master, slave), для ведущего и ведомого концов соответственно.

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

Создаёт процесс и подключает его управляющий терминал к стандартному вводу-выводу текущего процесса. Это часто используется, чтобы обмануть программы, которые настаивают на чтении из управляющего терминала.

Функции master_read и stdin_read должны читать из файлового дескриптора. По умолчанию при каждом вызове читается 1024 байта.

Изменено в версии 3.4: spawn() теперь возвращает код завершения от os.waitpid() для дочернего процесса.

35.8.1. ПримерExample

Следующая программа действует как команда 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)