在 Python 3 中,sys.stdin.read 将 unicode 字符作为单个字符返回。箭头键的转义序列作为多个 ASCII 字符提供。这是一个示例程序,使用tty 和termios,它会相应地解析输入。
import sys,tty,termios
# Commands and escape codes
END_OF_TEXT = chr(3) # CTRL+C (prints nothing)
END_OF_FILE = chr(4) # CTRL+D (prints nothing)
CANCEL = chr(24) # CTRL+X
ESCAPE = chr(27) # Escape
CONTROL = ESCAPE +'['
# Escape sequences for terminal keyboard navigation
ARROW_UP = CONTROL+'A'
ARROW_DOWN = CONTROL+'B'
ARROW_RIGHT = CONTROL+'C'
ARROW_LEFT = CONTROL+'D'
KEY_END = CONTROL+'F'
KEY_HOME = CONTROL+'H'
PAGE_UP = CONTROL+'5~'
PAGE_DOWN = CONTROL+'6~'
# Escape sequences to match
commands = {
ARROW_UP :'up arrow',
ARROW_DOWN :'down arrow',
ARROW_RIGHT:'right arrow',
ARROW_LEFT :'left arrow',
KEY_END :'end',
KEY_HOME :'home',
PAGE_UP :'page up',
PAGE_DOWN :'page down',
}
# Blocking read of one input character, detecting appropriate interrupts
def getch():
k = sys.stdin.read(1)[0]
if k in {END_OF_TEXT, END_OF_FILE, CANCEL}: raise KeyboardInterrupt
print('raw input 0x%X'%ord(k),end='\r\n')
return k
# Println for raw terminal mode
def println(*args):
print(*args,end='\r\n',flush=True)
# Preserve current terminal settings (we will restore these before exiting)
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
# Enter raw mode (key events sent directly as characters)
tty.setraw(sys.stdin.fileno())
# Loop, waiting for keyboard input
while 1:
# Parse known command escape sequences
read = getch()
while any(k.startswith(read) for k in commands.keys()):
if read in commands:
println('detected command (%s)'%commands[read])
read = ''
break
read += getch()
# Interpret all other inputs as text input
for c in read:
println('detected character 0x%X %c'%(ord(c),c))
# Always clean up
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
println('')
sys.exit(0)