pty
— Псевдотерминальные утилиты
Модуль pty
определяет операции для обработки концепции псевдотерминала:
запуск другого процесса и возможность программной записи и чтения с
управляющего терминала.
Поскольку обработка псевдотерминала сильно зависит от платформы, существует код только для Linux. (Предполагается, что код Linux будет работать и на других платформах, но он ещё не тестировался.)
Модуль pty
определяет следующие функции:
-
pty.
fork
() Вилка. Подключает управляющий терминал ребенка к псевдотерминалу. Возвращаемое значение —
(pid, fd)
. Обратите внимание, что потомок получает pid 0, а fd — invalid. Возвращаемое значение родителя — это pid дочернего элемента, а fd — это файловый дескриптор, подключенный к управляющему терминалу дочернего элемента (а также к стандартному вводу и выводу дочернего элемента).
-
pty.
openpty
() Открывает новую пару псевдотерминалов, если возможно используя
os.openpty()
или код эмуляции для общих Unix систем. Возвращает пару файловых дескрипторов(master, slave)
для ведущего и подчиненного конца соответственно.
-
pty.
spawn
(argv[, master_read[, stdin_read]]) Создаёт процесс и соединяет его управляющий терминал со стандартным вводом-выводом текущего процесса. Часто используется, чтобы сбить с толку программы, которые настаивают на чтении с управляющего терминала. Ожидается, что порожденный pty процесс, в конечном итоге завершится, и когда это произойдет, spawn вернётся.
Функциям master_read и stdin_read передаётся дескриптор файла, из которого они должны читать, и они всегда должны возвращать строку байтов. Чтобы заставить spawn вернуться до завершения дочернего процесса, следует вызвать
OSError
.Реализация по умолчанию для обеих функций будет считывать и возвращать до 1024 байт при каждом вызове функции. Обратному вызову master_read передаётся главный файловый дескриптор псевдотерминала для чтения выходных данных дочернего процесса, а stdin_read передаётся файловый дескриптор 0 для чтения из стандартного ввода родительского процесса.
Возвращение пустой строки байтов из любого обратного вызова интерпретируется как условие конца файла (EOF), и после этого обратный вызов не будет вызываться. Если stdin_read сигнализирует EOF, управляющий терминал больше не может взаимодействовать с родительским процессом ИЛИ дочерним процессом. Если дочерний процесс не завершится без какого-либо ввода, spawn будет зацикливаться навсегда. Если master_read сигнализирует EOF, происходит то же самое поведение (по крайней мере, в Linux).
Если оба обратных вызова сигнализируют EOF, то spawn, вероятно, никогда не вернётся, если только select не выдаст ошибку на вашей платформе при передаче трёх пустых списков. Данная ошибка задокументирована в issue 26228.
Вызывает событие аудита
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)