2009-06-27 4 views
4

Jedes Mal, wenn ich das Rezept bei http://code.activestate.com/recipes/134892/ benutze, kann ich nicht scheinen, dass es funktioniert. Es wirft immer folgende Fehlermeldung:Das Lesen eines einzelnen Zeichens (getch-Stil) in Python funktioniert unter Unix nicht

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

Mein bester Gedanke ist, dass es ist, weil ich es in Eclipse läuft bin so termios ist ein Sitz um den Dateideskriptor zu werfen.

Antwort

9

Dies funktioniert auf Ubuntu 8.04.1, Python 2.5.2, ich bekomme keinen solchen Fehler. Vielleicht sollten Sie es von der Befehlszeile aus versuchen, Eclipse kann seine eigene stdin verwenden, ich bekomme genau den gleichen Fehler, wenn ich es von Wing IDE ausführe, aber von der Befehlszeile funktioniert es großartig. Grund ist, dass die IDE wing z. B. dort eigene Klasse netserver.CDbgInputStream als sys.stdin verwendet, so sys.stdin.fileno ist Null, das ist der Grund, warum. Grundsätzlich IDE stdin ist kein tty (Print sys.stdin.isatty() ist 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() 
+0

Ausführen von der Befehlszeile löste das Problem. –

+0

+100 FANTASTISCH! Vielen Dank! – hasen

+0

Funktioniert nicht mit Pfeiltasten - lässt zusätzliche Zeichen im Puffer. –

3

Putting Terminal in Raw-Modus ist nicht immer eine gute Idee. Eigentlich reicht es, das ICANON-Bit zu löschen. Hier ist eine andere Version von getch() mit Timeout-Unterstützung:

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() 
Verwandte Themen