Python 将输出重定向到文件时,raw_input()提示消失
我正在编写一个CLI,它接受电子邮件和身份验证密码。 电子邮件提示使用Python 将输出重定向到文件时,raw_input()提示消失,python,Python,我正在编写一个CLI,它接受电子邮件和身份验证密码。 电子邮件提示使用raw_input(),密码提示使用getpass()进行混淆 直接输出到控制台时,此设置工作正常,但将输出重定向到日志文件时会出现问题 示例代码: user\u email=原始输入('email:')) 用户\u password=getpass('password:') 无重定向的示例输出: 带有重定向的示例输出: 因为我知道这里需要用户输入,所以我可以键入电子邮件,按enter键,然后显示: $ python scr
raw_input()
,密码提示使用getpass()
进行混淆
直接输出到控制台时,此设置工作正常,但将输出重定向到日志文件时会出现问题
示例代码:
user\u email=原始输入('email:'))
用户\u password=getpass('password:')
无重定向的示例输出:
带有重定向的示例输出:
因为我知道这里需要用户输入,所以我可以键入电子邮件,按enter键,然后显示:
$ python script_that_does_stuff.py > stuff.log
me@email.com
Password:
输入密码后,它会像往常一样继续,但日志显示如下:
$ cat stuff.log
Email:Doing stuff...
问题:
如何强制raw\u input()
提示符显示在控制台中,就像将输出重定向到文件时的getpass()
提示符一样
环境
此脚本存在于传统的Python 2.7代码库中,主要在Mac OS系统上运行,偶尔在Linux上运行。根据getpass([prompt[,stream]])
有第二个可选参数,该参数指示要将提示打印到的输出流(stderr
)
重定向输出(stdout
)时,getpass
的提示符仍打印到stderr
,但raw\u input
不支持设置输出流,因此其提示符重定向到目标文件
因此,为了解决您的问题,您还必须将电子邮件提示打印到
stderr
。您可以临时覆盖sys.stdout
,以写入终端。比如说,
import contextlib
import sys
@contextlib.contextmanager
def output_to_terminal():
try:
with open("/dev/tty") as f:
sys.stdout = f
yield
finally:
# Ensure sys.stdout is restored in the event of an error
sys.stdout = sys.__stdout__
with output_to_terminal():
x = raw_input("> ")
print(x)
(这是独立派生的;您可能需要检查Python 3的重定向\u stdout
的源代码,也可以在contextlib
模块中找到,并将其向后移植以供您使用。)关于另一个问题,我似乎可以回答
简而言之,创建一个自定义输入函数:
def email_输入(提示符=无):
如果提示:
sys.stderr.write(str(提示符))
返回原始输入()
然后调用代码变为:
user\u email=email\u输入('email:'))
用户\u password=getpass('password:')
这将导致电子邮件和密码提示被发送到stderr(打印到控制台),而不会影响重定向的日志输出
$ cat stuff.log
Email:Doing stuff...
import contextlib
import sys
@contextlib.contextmanager
def output_to_terminal():
try:
with open("/dev/tty") as f:
sys.stdout = f
yield
finally:
# Ensure sys.stdout is restored in the event of an error
sys.stdout = sys.__stdout__
with output_to_terminal():
x = raw_input("> ")
print(x)