在Python /终端的函数运行期间阻止命令行使用?

时间:2017-04-29 03:35:20

标签: python

我使用Terminal运行带有一系列print语句的python脚本,用time.sleep函数分隔。

如果我在10秒钟内打印各种项目,我希望能够阻止用户在此期间将新命令输入命令行。

终端可以吗?有解决办法吗?

我的目标是能够为用户提供大量的打印报表,然后让他们只在提出问题之后回答问题

因为我不想让用户感到压力,所以我想延迟打印报表的时间,使其看起来更易于管理(好吧,它真的是戏剧效果)。

example.com:2083

现在,用户可以在询问问题之前输入回复,并且仍在吃芝士汉堡。我想阻止这一点。

2 个答案:

答案 0 :(得分:3)

问题是特定于平台的问题,因为不同的操作系统处理标准输入和输出的方式不同。我将尝试回答您关于Linux的问题:

您可以使用os.system访问linux命令stty -echo以使终端上输入的任何文本不可见,并stty echo使其再次可见。

您要实现的下一件事是在询问用户输入时清除stdin缓冲区。这可以通过termios函数tcflush来实现,该函数可用于刷新已接收但尚未被终端读取的所有输入。

import os
import time
import termios
import sys

os.system("stty -echo")
for i in range(10):
    print(i)
    time.sleep(1)
os.system("stty echo")

termios.tcflush(sys.stdin, termios.TCIOFLUSH)

print(raw_input("Answer now:"))

答案 1 :(得分:0)

以下是使用ctypes为Windows控制台编写的Saurabh Shirodkar's answer版本。

import sys
import msvcrt
import ctypes

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

ENABLE_ECHO_INPUT = 0x0004

def _check_bool(result, func, args):
    if not result:
        raise ctypes.WinError(ctypes.get_last_error())
    return args

kernel32.GetConsoleMode.errcheck = _check_bool
kernel32.GetConsoleMode.argtypes = (ctypes.c_void_p,
    ctypes.POINTER(ctypes.c_ulong))
kernel32.SetConsoleMode.errcheck = _check_bool
kernel32.SetConsoleMode.argtypes = (ctypes.c_void_p, ctypes.c_ulong)
kernel32.FlushConsoleInputBuffer.errcheck = _check_bool
kernel32.FlushConsoleInputBuffer.argtypes = (ctypes.c_void_p,)

def echo_input(enable=True, conin=sys.stdin):
    h = msvcrt.get_osfhandle(conin.fileno())
    mode = ctypes.c_ulong()
    kernel32.GetConsoleMode(h, ctypes.byref(mode))
    if enable:
        mode.value |= ENABLE_ECHO_INPUT
    else:
        mode.value &= ~ENABLE_ECHO_INPUT
    kernel32.SetConsoleMode(h, mode)

def flush_input(conin=sys.stdin):
    h = msvcrt.get_osfhandle(conin.fileno())
    kernel32.FlushConsoleInputBuffer(h)

if __name__ == '__main__':
    import time

    if sys.version_info[0] == 2:
        input = raw_input

    echo_input(False)

    for i in range(10):
        print(i)
        time.sleep(1)

    echo_input(True)
    flush_input()

    print(input("Answer now: "))