pty — Утилиты псевдотерминалов
Исходный код: Lib/pty.py
Модуль pty определяет операции для обработки концепции псевдотерминала: запуск другого процесса и возможность программно писать в него и читать из него данные.
Доступность: Unix.
Обработка псевдотерминалов сильно зависит от платформы. Этот код в основном тестировался на Linux, FreeBSD и macOS (он должен работать и на других POSIX-платформах, но не был полностью протестирован).
Модуль pty определяет следующие функции:
-
pty.fork() -
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]]) -
Запускает процесс и подключает его управляющий терминал к стандартному вводу-выводу текущего процесса. Это часто используется для обмана программ, которые настаивают на чтении из управляющего терминала. Ожидается, что процесс, запущенный через 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()для дочернего процесса.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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/pty.html