如何在 tty.setcbreak() 后重新开启控制台回显
我正在使用这个命令来关闭回显,并通过 sys.stdin.read(1)
获取用户输入。
tty.setcbreak(sys.stdin.fileno())
但是在我的程序运行过程中,我需要再次开启和关闭控制台的回显。我尝试了
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
termios.tcsetattr(fd, termios.TCSADRAIN, old)
但这并没有奏效。我该如何优雅地开启回显呢?
顺便说一下,我使用的是 Python 非阻塞控制台输入 这篇文章中的代码,作者是mizipzor。
这是代码:
import sys
import select
import tty
import termios
import time
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
def calc_time(traw):
tfactor = {
's': 1,
'm': 60,
'h': 3600,
}
if is_number(g[:-1]):
return float(g[:-1]) * tfactor.get(g[-1])
else:
return None
def isData():
return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])
old_settings = termios.tcgetattr(sys.stdin)
try:
tty.setcbreak(sys.stdin.fileno())
i = 0
while 1:
print i
i += 1
time.sleep(.1)
if isData():
c = sys.stdin.read(1)
if c:
if c == 'p':
print """Paused. Use the Following commands now:
Hit 'n' to skip and continue with next link.
Hit '5s' or '3m' or '2h' to wait for 5 secs, 3 mins or 3 hours
Hit Enter to continue from here itself.
Hit Escape to quit this program"""
#expect these lines to enable echo back again
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
old[3] = old[3] & termios.ECHO
termios.tcsetattr(fd, termios.TCSADRAIN, old)
g = raw_input("(ENABLE ECHO HERE):")
if g == '\x1b':
print "Escaping..."
break
if g == 'n':
#log error
continue
elif g[-1] in ['s','m','h']:
tval = calc_time(g)
if tval is not None:
print "Waiting for %s seconds."%(tval)
time.sleep(tval)
continue
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
2 个回答
5
如果你看看文档,里面有一个例子:
http://docs.python.org/library/termios.html#module-termios
你缺少了开启回显标志的设置:
old[3] = old[3] | termios.ECHO
所以,整个过程是:
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
old[3] = old[3] | termios.ECHO
termios.tcsetattr(fd, termios.TCSADRAIN, old)
5
写成这样:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
这样写就解决了上面提到的四行代码的问题。