Pregunta

Cada vez que uso la receta en http://code.activestate.com/recipes/134892 / Parece que no puedo hacer que funcione. Siempre arroja el siguiente error:

Traceback (most recent call last):
    ...
    old_settings = termios.tcgetattr(fd)
termios.error: (22, 'Invalid argument)

Mi mejor pensamiento es que es porque lo estoy ejecutando en Eclipse, por lo que termios está encajando con el descriptor de archivos.

¿Fue útil?

Solución

Esto está funcionando en Ubuntu 8.04.1, Python 2.5.2, no obtengo tal error. Puede ser que deba probarlo desde la línea de comandos, eclipse puede estar usando su propio stdin, obtengo exactamente el mismo error si lo ejecuto desde Wing IDE, pero desde la línea de comandos funciona muy bien. La razón es que IDE, por ejemplo, Wing está utilizando su propia clase netserver.CDbgInputStream como sys.stdin entonces sys.stdin.fileno es cero, por eso el error. Básicamente, IDE stdin no es un tty (print sys.stdin.isatty () es False)

class _GetchUnix:
    def __init__(self):
        import tty, sys

    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch


getch = _GetchUnix()

print getch()

Otros consejos

Poner el terminal en modo sin procesar no siempre es una buena idea. En realidad, es suficiente para borrar el bit ICANON. Aquí hay otra versión de getch () con soporte de tiempo de espera:

import tty, sys, termios
import select

def setup_term(fd, when=termios.TCSAFLUSH):
    mode = termios.tcgetattr(fd)
    mode[tty.LFLAG] = mode[tty.LFLAG] & ~(termios.ECHO | termios.ICANON)
    termios.tcsetattr(fd, when, mode)

def getch(timeout=None):
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        setup_term(fd)
        try:
            rw, wl, xl = select.select([fd], [], [], timeout)
        except select.error:
            return
        if rw:
            return sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

if __name__ == "__main__":
    print getch()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top