os.openpty(), forkpty(), login_tty() și funcțiile pentru pseudo-terminale în Python

Descriptori de fișiere (os) Python 3.0+ (login_tty: 3.11+, posix_openpt/grantpt/unlockpt/ptsname: 3.13+)

Creează pseudo-terminale, prin care un program poate controla altul ca și cum ar fi un utilizator la tastatură.

Sintaxă
master, slave = os.openpty()
pid, fd = os.forkpty()
os.login_tty(fd)
fd = os.posix_openpt(flaguri); os.grantpt(fd); os.unlockpt(fd); os.ptsname(fd)

Ce face os.openpty(), forkpty(), login_tty() și funcțiile pentru pseudo-terminale

Un pseudo-terminal (PTY) are două capete: „master”, controlat de programul tău, și „slave”, care pentru programul pornit arată exact ca un terminal real. Așa funcționează emulatoarele de terminal, ssh și instrumentele care automatizează programe interactive.

openpty() returnează perechea de descriptori. forkpty() face fork și leagă procesul copil la capătul slave. login_tty(fd) face din fd terminalul de control al procesului. Funcțiile POSIX posix_openpt(), grantpt(), unlockpt() și ptsname() (3.13+) creează pas cu pas un PTY. Modulul pty oferă variante de nivel înalt.

Ce returnează

Descriptori, perechi (pid, fd) sau numele terminalului.

Exemple

Exemplul 1: Un program care „vede” un terminal

import os
master, slave = os.openpty()
print(os.isatty(slave), flush=True)
pid, fd = os.forkpty()
if pid == 0:
    print("copil: stdout este terminal?", os.isatty(1), flush=True)
    os._exit(0)
print(os.read(fd, 100).decode().strip())
os.waitpid(pid, 0)
m = os.posix_openpt(os.O_RDWR | os.O_NOCTTY)
os.grantpt(m)
os.unlockpt(m)
print(os.ptsname(m).startswith("/dev/"))

Rezultat

True
copil: stdout este terminal? True
True

Exemplul 2: login_tty

import os
master, slave = os.openpty()
pid = os.fork()
if pid == 0:
    os.close(master)
    os.login_tty(slave)
    os.execlp("tty", "tty")
os.close(slave)
print(os.read(master, 100).decode().strip())
os.waitpid(pid, 0)

Rezultat posibil (diferă la fiecare rulare)

/dev/ttys004

Greșeli frecvente

  • Citești din capătul master după ce copilul s-a terminat, pe Linux, și primești OSError: [Errno 5] Input/output error în loc de sfârșit de fișier. Tratează această eroare ca sfârșit.

Comenzi înrudite