Spec-Zone.ru › Python 3.12

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 вернёт управление.

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

Функциям 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), используя псевдотерминал для записи всех входных и выходных данных сеанса терминала в «текстовый журнал».

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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/pty.html

Spec-Zone.ru

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