<p>默认情况下,标准输入是缓冲的,并使用规范模式。这允许您编辑输入。按enter键时,Python可以读取输入</p>
<p>如果希望对输入进行较低级别的访问,可以在标准输入文件描述符上使用<code>tty.setraw()</code>。这允许您使用<code>sys.stdin.read(1)</code>一次读取一个字符。请注意,在这种情况下,Python脚本将负责处理特殊字符,您将失去一些功能,如字符回音和删除。有关更多信息,请参阅<a href="https://manpages.debian.org/termios(3)" rel="nofollow noreferrer">termios(3)</a></p>
<p>你可以在维基百科上阅读关于<a href="https://en.wikipedia.org/wiki/ANSI_escape_code#Escape_sequences" rel="nofollow noreferrer">escape sequences</a>的信息,这些信息用于<a href="https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences" rel="nofollow noreferrer">up and down keys</a></p>
<p>如果您在一个进程中处理所有事情,那么您应该能够复制标准的shell行为</p>
<p>您可能还希望尝试使用子流程(不引用模块-您可以使用<code>fork()</code>或<code>popen()</code>)。您将在主进程中解析未缓冲的输入,并将其发送到子进程的stdin(可以缓冲)。您可能需要进行一些进程间通信,以便与主进程共享历史</p>
<p>下面是以这种方式捕获输入所需的代码示例。注意,它只是做一些基本的处理,需要做更多的工作才能适合您的用例</p>
<pre><code>import sys
import tty
import termios
def getchar():
fd = sys.stdin.fileno()
attr = termios.tcgetattr(fd)
try:
tty.setraw(fd)
return sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSANOW, attr)
EOT = '\x04' # CTRL+D
ESC = '\x1b'
CSI = '['
line = ''
while True:
c = getchar()
if c == EOT:
print('exit')
break
elif c == ESC:
if getchar() == CSI:
x = getchar()
if x == 'A':
print('UP')
elif x == 'B':
print('DOWN')
elif c == '\r':
print([line])
line = ''
else:
line += c
</code></pre>