如何在 tty.setcbreak() 之后重新打开控制台回显

jer*_*use 3 python

我正在使用此命令来禁用回显并使用以下命令获取用户输入sys.stdin.read(1)

tty.setcbreak(sys.stdin.fileno())
Run Code Online (Sandbox Code Playgroud)

然而,在我的程序过程中,我需要再次启用和禁用控制台回显。我试过

fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
termios.tcsetattr(fd, termios.TCSADRAIN, old)
Run Code Online (Sandbox Code Playgroud)

但这是行不通的。如何优雅地启用回显?

ps:我使用的是mizipzor 的Python 非阻塞控制台输入的代码

代码如下:

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)
Run Code Online (Sandbox Code Playgroud)

Dav*_*ess 5

如果您查看文档,那里有一个示例:

http://docs.python.org/library/termios.html#module-termios

您缺少 echo 标志的设置:

old[3] = old[3] | termios.ECHO
Run Code Online (Sandbox Code Playgroud)

所以,整个事情是:

fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
old[3] = old[3] | termios.ECHO
termios.tcsetattr(fd, termios.TCSADRAIN, old)
Run Code Online (Sandbox Code Playgroud)


jer*_*use 5

写这个:

termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
Run Code Online (Sandbox Code Playgroud)

而不是上面4行解决了它。