pty — Utilidades para Pseudo-terminal

Código Fuente: Lib/pty.py


El módulo pty define las operaciones para manejar el concepto de pseudo-terminal: iniciar otro proceso para poder escribir y leer desde su propia terminal mediante programación.

Pseudo-terminal handling is highly platform dependent. This code is mainly tested on Linux, FreeBSD, and macOS (it is supposed to work on other POSIX platforms but it’s not been thoroughly tested).

El modulo pty define las siguientes funciones:

pty.fork()

Bifurcación. Conectar en su propia terminal (terminal hijo) una pseudo-terminal. El valor de retorno es (pid, fd). Tener en cuenta que la terminal hijo tiene como valor pid 0 y fd es invalid. El valor de retorno del padre es el pid del hijo, y fd es un descriptor de archivo conectado a la terminal hijo (también a la salida y entrada estándar de la terminal hijo)

pty.openpty()

Abre un nuevo par de pseudo-terminales, usando os.openpty(), o código de emulación para sistemas genéricos de Unix. Retorna un par de descriptores de archivo (master, slave), para el master y el slave respectivamente.

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

Genera un proceso conectado a su terminal con el io estándar del proceso actual. Esto se usa a frecuentemente para confundir programas que insisten en leer desde la terminal de control. Se espera que el proceso generado detrás de pty sea finalizado y cuando lo haga spawn se retornará.

A loop copies STDIN of the current process to the child and data received from the child to STDOUT of the current process. It is not signaled to the child if STDIN of the current process closes down.

The functions master_read and stdin_read are passed a file descriptor which they should read from, and they should always return a byte string. In order to force spawn to return before the child process exits an empty byte array should be returned to signal end of file.

La implementación predeterminada para ambas funciones retornará hasta 1024 bytes cada vez que se llamen. El dato retornado de master_read se pasa al descriptor de archivo maestro para leer la salida del proceso hijo, y stdin_read pasa el descriptor de archivo 0, para leer desde la entrada del proceso padre.

Retornando una cadena de bytes vacía de cualquier llamado es interpretado como una condición de fin de archivo (EOF), y el llamado no se realizará después de eso. Si stdin_read retorna EOF la terminal de control ya no puede comunicarse con el proceso padre o el proceso hijo. A menos que el proceso hijo se cierre sin ninguna entrada spawn se repetirá para siempre. Si master_read retorna EOF se produce el mismo comportamiento (al menos en Linux)

Retorna el valor del estado de salida de os.waitpid() en el proceso hijo.

waitstatus_to_exitcode() se puede utilizar para convertir el estado de salida en un código de salida.

Lanza un evento de auditoria pty.spawn con el argumento argv.

Distinto en la versión 3.4: spawn() ahora retorna el valor de estado de os.waitpid() para los procesos hijos.

Ejemplo

El siguiente programa actúa como el comando de Unix script(1), usando una pseudo-terminal para registrar todas las entradas y salidas de una sesión en «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)