El módulo termios expone el control POSIX de terminales TTY en Unix. Permite activar o desactivar echo, cambiar entre entrada canónica y lectura carácter por carácter, configurar velocidades seriales, gestionar colas y consultar el tamaño de la ventana.
Estas operaciones modifican estado compartido del terminal asociado al file descriptor. Si el programa termina sin restaurarlo, el shell puede quedar sin echo, con teclas de control desactivadas o en un modo aparentemente roto. Guarda siempre los atributos originales y restáuralos en finally.
Disponibilidad
termios solo existe en Unix con soporte POSIX TTY. Windows usa APIs distintas y el descriptor debe estar conectado a un terminal real.
import os
import sys
if not os.isatty(sys.stdin.fileno()):
raise RuntimeError("stdin no está conectado a un TTY")
La entrada redirigida desde un pipe o archivo no tiene los mismos atributos.
Estructura de tcgetattr()
tcgetattr(fd) devuelve siete elementos:
[iflag, oflag, cflag, lflag, ispeed, ospeed, cc]
Representan flags de entrada, salida, control y comportamiento local, velocidades y caracteres especiales. Interpreta todo mediante constantes simbólicas de termios.
Guardar y restaurar
import sys
import termios
fd = sys.stdin.fileno()
original = termios.tcgetattr(fd)
nuevo = termios.tcgetattr(fd)
try:
nuevo[3] &= ~termios.ECHO
termios.tcsetattr(fd, termios.TCSADRAIN, nuevo)
secreto = input("Contraseña: ")
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, original)
print()
Haz dos llamadas o una copia profunda porque la lista cc es mutable. Una copia superficial puede compartirla.
Cuándo aplicar cambios
TCSANOW aplica de inmediato. TCSADRAIN espera la salida pendiente. TCSAFLUSH también descarta entrada no leída.
Para desactivar echo en un prompt, TCSADRAIN evita cortar texto ya enviado.
Echo
El bit ECHO controla si los caracteres aparecen en pantalla.
atributos[3] &= ~termios.ECHO
Desactivar echo no vuelve la captura automáticamente segura. Para contraseñas comunes, prefiere getpass.getpass().
Modo canónico
Con ICANON activo, la entrada llega después de Enter y el driver realiza edición básica. Al desactivarlo, las lecturas pueden devolver datos antes de una línea completa.
atributos[3] &= ~termios.ICANON
El modo no canónico sirve para juegos, hotkeys e interfaces en pantalla completa, pero obliga a procesar bytes y secuencias de escape.
VMIN y VTIME
En cc, VMIN y VTIME controlan las lecturas no canónicas.
atributos[6][termios.VMIN] = 1
atributos[6][termios.VTIME] = 0
VMIN 1 y VTIME 0 espera al menos un byte. VMIN 0 con VTIME positivo crea un timeout en décimas de segundo.
Leer una tecla
import os
import sys
import termios
fd = sys.stdin.fileno()
original = termios.tcgetattr(fd)
nuevo = termios.tcgetattr(fd)
nuevo[3] &= ~(termios.ICANON | termios.ECHO)
nuevo[6][termios.VMIN] = 1
nuevo[6][termios.VTIME] = 0
try:
termios.tcsetattr(fd, termios.TCSADRAIN, nuevo)
tecla = os.read(fd, 1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, original)
print(tecla)
Una tecla visible puede generar varios bytes. Las flechas y teclas de función producen secuencias de escape.
Unicode
os.read() devuelve bytes. Un carácter UTF-8 puede ocupar varios, por lo que un byte no equivale necesariamente a un carácter.
Usa un decoder incremental o analiza el protocolo del terminal.
Señales y teclas de control
ISIG permite que Ctrl+C y Ctrl+Z generen señales. Desactivarlo convierte esos bytes en entrada normal.
Ofrece otra tecla de salida y restaura el estado tras excepciones. Consulta signal en Python.
Mapeo de entrada
ICRNL, INLCR e IGNCR controlan conversiones entre carriage return y newline. Modificarlos afecta Enter y protocolos seriales.
Cambia solo los bits necesarios.
Procesamiento de salida
OPOST habilita transformaciones de salida. Un modo raw puede desactivarlo, alterando también el comportamiento de newline y cursor.
Para casos comunes, usa funciones de tty o una biblioteca de terminal completa.
Flags de hardware
cflag incluye tamaño de carácter, paridad, stop bits y control de flujo. Son importantes en puertos seriales.
Una configuración incorrecta puede producir datos ilegibles o bloquear la comunicación.
Baud rate
ispeed y ospeed usan constantes como B9600 y B115200.
atributos[4] = termios.B115200
atributos[5] = termios.B115200
No todas las velocidades están disponibles. Para producción, pyserial suele ser más portable.
tcdrain()
tcdrain(fd) espera que toda la salida en cola se transmita. Es útil antes de cambiar parámetros o cerrar un dispositivo serial.
Puede bloquear si el hardware está lento o desconectado.
tcflush()
termios.tcflush(fd, termios.TCIFLUSH)
TCIFLUSH descarta entrada, TCOFLUSH salida y TCIOFLUSH ambas. Descartar salida puede perder comandos ya aceptados.
Control de flujo
tcflow() suspende o reanuda entrada o salida con acciones como TCOOFF y TCOON. No lo confundas con control de flujo de hardware.
Enviar break
tcsendbreak(fd, duration) envía una condición break en líneas seriales. Duración cero significa aproximadamente 0,25 a 0,5 segundos; otros valores dependen del sistema.
Tamaño de ventana
Desde Python 3.11, tcgetwinsize() devuelve filas y columnas.
filas, columnas = termios.tcgetwinsize(sys.stdout.fileno())
print(filas, columnas)
tcsetwinsize() establece el tamaño cuando la plataforma lo soporta, algo útil con pseudo-terminales.
SIGWINCH
Después de un resize, procesos Unix suelen recibir SIGWINCH. Haz que el handler marque una flag y recalcula el layout en el loop principal.
El conjunto final sobre curses cubre interfaces de pantalla completa.
Context manager reutilizable
from contextlib import contextmanager
import termios
@contextmanager
def atributos_temporales(fd, modificar):
original = termios.tcgetattr(fd)
nuevo = termios.tcgetattr(fd)
modificar(nuevo)
try:
termios.tcsetattr(fd, termios.TCSADRAIN, nuevo)
yield
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, original)
Centralizar la restauración reduce rutas de error olvidadas.
Fork y subprocesses
Los hijos pueden heredar el mismo terminal y observar atributos temporales. Evita iniciar procesos ajenos mientras el TTY está modificado.
Usa un pseudo-terminal cuando necesites aislar una aplicación interactiva.
Threads
El estado pertenece al terminal, no al thread. Dos threads cambiando flags pueden restaurar valores fuera de orden. Centraliza el control en uno solo.
Recuperación manual
Si una aplicación deja el terminal sin echo, stty sane suele restaurar un estado razonable. Documenta el comando en herramientas experimentales.
Pruebas
Prueba terminal real y entrada redirigida, Ctrl+C, excepción durante lectura, Unicode, flechas, resize, subprocesses, serial, VMIN/VTIME y restauración tras fallo.
Usa pty para tests automatizados, pero también prueba manualmente.
Errores comunes
Los fallos frecuentes son omitir finally, modificar la lista original, hacer copia superficial de cc, asumir una tecla por byte, desactivar ISIG sin salida alternativa, operar sobre stdin redirigido y cambiar demasiadas flags.
Conclusión
termios proporciona control preciso de terminales POSIX y puertos seriales. Úsalo cuando necesites flags de bajo nivel; para tareas comunes, prefiere tty, getpass, curses o bibliotecas especializadas.
Guarda y restaura el estado, cambia solo los bits necesarios y prueba en el Unix objetivo. Consulta la documentación oficial de termios y termios(3).







