pty — Utilitários de pseudoterminal

Código-fonte: Lib/pty.py


O módulo pty define operações para lidar com o conceito de pseudoterminal: iniciar outro processo e poder gravar e ler de seu terminal de controle programaticamente.

Because pseudo-terminal handling is highly platform dependent, there is code to do it only for Linux. (The Linux code is supposed to work on other platforms, but hasn’t been tested yet.)

O módulo pty define as seguintes funções:

pty.fork()

Faz um fork. Conecta o terminal de controle do filho a um pseudoterminal. O valor de retorno é (pid, fd). Observe que a criança recebe pid 0 e o fd é inválido. O valor de retorno do pai é o pid do filho, e o fd é um descritor de arquivo conectado ao terminal de controle do filho (e também à entrada e à saída padrão do filho).

pty.openpty()

Abre um novo par de pseudoterminais, usando os.openpty(), se possível, ou código de emulação para sistemas genérico Unix . Retorna um par de descritores de arquivo (master, slave), para a extremidade mestre e escrava, respectivamente.

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

Gera um processo e conecta seu terminal de controle com o E/S padrão do processo atual. Isso é frequentemente usado para confundir programas que insistem em ler no terminal de controle. Espera-se que o processo gerado por trás do pty acabe sendo encerrado e, quando isso acontecer, o spawn é retornado.

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 OSError should be thrown.

A implementação padrão para ambos os funções vai ler e retornar até 1024 bytes cada vez que a função for chamada. A função de retorno master_read é passada para o descritor de arquivo mestre do pseudoterminal para ler a saída do processo filho, e ao stdin_read é passado o descritor de arquivo 0, para ler a entrada padrão do processo pai.

Retornar uma string de bytes vazia de qualquer uma das funções de retorno é interpretado como uma condição de fim de vida (EOF), e que a função de retorno não será chamada depois disso. Se stdin_read sinalizar EOF, o terminal de controle não poderá mais se comunicar com o processo pai OU o processo filho. A menos que o filho processar seja encerrado sem nenhuma entrada, spawn vai então fazer o laço para sempre. Se master_read sinalizar EOF, os mesmos comportamento resultados (pelo menos no Linux).

If both callbacks signal EOF then spawn will probably never return, unless select throws an error on your platform when passed three empty lists. This is a bug, documented in issue 26228.

Retorna o valor de status de saída de os.waitpid() no processo filho.

waitstatus_to_exitcode() pode ser usado para converter o status de saída em um código de saída.

Levanta um evento de auditoria pty.spawn com o argumento argv.

Alterado na versão 3.4: spawn() agora retorna o valor de status de os.waitpid() no processo filho.

Exemplo

O programa a seguir funciona como o comando Unix script(1) , usando um pseudoterminal para registrar todas as entradas e saídas de uma sessão de terminal em um “script”.

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)