Spec-Zone.ru › Python 3.13

pty — Утилиты псевдотерминала

Исходный код: Lib/pty.py

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

Доступность: Unix.

Работа с псевдотерминалами сильно зависит от платформы. Этот код в основном тестируется в Linux, FreeBSD и macOS (предполагается, что он работает и на других POSIX-платформах, но это не было тщательно проверено).

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

pty.fork()

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

Предупреждение

В macOS использование этой функции небезопасно при сочетании с высокоуровневыми системными API, в том числе с использованием urllib.request.

pty.openpty()

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

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

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

Цикл копирует STDIN текущего процесса в дочерний процесс, а данные, полученные от дочернего процесса, — в STDOUT текущего процесса. Дочерний процесс не получает сигнала, если STDIN текущего процесса закрывается.

Функциям master_read и stdin_read передаётся файловый дескриптор, из которого они должны считывать данные; они всегда должны возвращать байтовую строку. Чтобы заставить spawn вернуться до завершения дочернего процесса, следует вернуть пустой массив байтов, обозначающий конец файла.

Реализация обеих функций по умолчанию при каждом вызове считывает и возвращает не более 1024 байт. Обратному вызову master_read передаётся главный файловый дескриптор псевдотерминала для чтения вывода дочернего процесса, а stdin_read передаётся файловый дескриптор 0 для чтения стандартного ввода родительского процесса.

Возвращение пустой байтовой строки из любого обратного вызова интерпретируется как условие конца файла (EOF), и после этого данный обратный вызов вызываться не будет. Если stdin_read сообщает EOF, управляющий терминал больше не может обмениваться данными с родительским ИЛИ дочерним процессом. Если дочерний процесс не завершится без ввода, функция spawn будет бесконечно выполнять цикл. Если EOF сообщает master_read, возникает такое же поведение (по крайней мере, в Linux).

Возвращает значение статуса завершения, полученное от os.waitpid() для дочернего процесса.

Для преобразования статуса завершения в код завершения можно использовать os.waitstatus_to_exitcode().

Вызывает событие аудита 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)

© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/pty.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API