如果您想完全避免在终端中显示输出,您可以在 MacOS 和 Linux 上使用以下命令:
import sys
import tty
import termios
def hidden_input(*args):
stdin = sys.stdin.fileno()
tattr = termios.tcgetattr(stdin)
try:
tty.setcbreak(stdin, termios.TCSANOW)
return input(*args)
finally:
termios.tcsetattr(stdin, termios.TCSANOW, tattr)
这可以通过将 TTY(99% 的时间是终端仿真器)设置为 cbreak 模式来实现。执行以下操作:
传统的“原始”模式更容易解释;它根本不对输入或输出进行内核处理。键入时立即返回所有字符,并且按原样生成所有输出。传统的“cbreak”模式用于密码输入等操作;它在输入字符时立即返回字符,不回显字符,也不进行任何内核内行编辑(这主要意味着您的程序实际上可以看到各种编辑字符)。在高层次上,'cbreak' 和 'raw' 之间有两个主要区别。首先,cbreak 保持输出处理不变,这可能相对“熟”。其次,cbreak 仍然允许您使用 ^C 中断程序,将其挂起,等等。您可以在大多数程序(例如 passwd、su、或 sudo) 要求输入密码;您可以立即用 ^C 以某种方式中断它们,例如 vi 不响应。
cbreak 的低级设置是:
- 禁用回声;这会阻止输入的字符被回显。
- 禁用 ICANON;这将关闭行编辑。将 VMIN 设置为 1,将 VTIME 设置为 0;这使得一旦有(至少)一个字符可用, read() 就会立即返回。
请注意,由于readline
仍在使用中,您仍然可以像正常输入一样编辑行。
在 Windows 上,我不确定如何轻松做到这一点。
如果你想清除用户按下回车后输入的输入,这有点困难,因为它需要部分清除已经打印的输出,这需要使用特殊的控制代码。
Windows 的一种可能更简单的解决方案:以下将清除 MacOS 和 Linux 上的整个终端,但也适用于Windows 终端(与默认的 cmd.exe 不同!)
print('\x1b[2J')
您也可以尝试通过colorama包使其与普通 Windows 终端一起使用,如 martineau 的评论中所建议的那样。