# `pty` — Pseudo-terminal utilities

Вихідний код: Lib/pty.py

The `pty` module defines operations for handling the pseudo-terminal concept: starting another process and being able to write to and read from its controlling terminal programmatically.

Availability: Unix.

Робота з псевдотерміналом сильно залежить від платформи. Цей код в основному тестується на Linux, FreeBSD і macOS (передбачається, що він працює на інших платформах POSIX, але не був ретельно протестований).

The `pty` module defines the following functions:

pty.fork()

  Вилка. Підключіть керуючий термінал дитини до псевдотерміналу. Повернене значення: `(pid, fd)`. Зверніть увагу, що дитина отримує pid 0, а fd є недійсним. Значенням, що повертає батьківський елемент, є pid дочірнього, а fd — це дескриптор файлу, підключений до керуючого терміналу дочірнього (а також до стандартного введення та виведення дочірнього).

  The returned file descriptor fd is non-inheritable.

  Попередження

  On macOS the use of this function is unsafe when mixed with using higher-level system APIs, and that includes using `urllib.request`.

  Змінено в версії 3.15: The returned file descriptor is now made non-inheritable.

pty.openpty()

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

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

  Створіть процес і підключіть його керуючий термінал до стандартного io поточного процесу. Це часто використовується, щоб збентежити програми, які наполягають на читанні з керуючого терміналу. Очікується, що процес, породжений за 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()` can be used to convert the exit status into an exit code.

  Викликає подію аудиту `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)