【问题标题】:raw_input() prompt disappears when redirecting output to file将输出重定向到文件时 raw_input() 提示消失
【发布时间】:2020-03-17 17:52:45
【问题描述】:

我正在编写一个接受电子邮件和密码进行身份验证的 CLI。 邮件提示使用raw_input(),密码提示使用getpass()进行混淆处理。

此设置在直接输出到控制台时工作正常,但在将输出重定向到日志文件时会失败。

示例代码:

    user_email = raw_input('Email: ')
    user_password = getpass('Password: ')

没有重定向的示例输出:

$ python script_that_does_stuff.py

Email: me@email.com
Password: 

Doing stuff...

带有重定向的示例输出:

$ python script_that_does_stuff.py > stuff.log

因为我知道这里需要用户输入,所以我可以输入电子邮件,按 Enter,然后它会显示:

$ python script_that_does_stuff.py > stuff.log
me@email.com
Password: 

输入密码后,照常继续,但日志显示如下:

$ cat stuff.log

Email:Doing stuff...

问题:

如何强制raw_input() 提示在控制台中显示,就像将输出重定向到文件时的getpass() 提示一样?

环境

此脚本位于旧版 Python 2.7 代码库中,主要在 Mac OS 系统上运行,偶尔在 Linux 上运行。

【问题讨论】:

    标签: python


    【解决方案1】:

    您可以临时覆盖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 的 redirect_stdout 的源代码,也可以在 contextlib 模块中找到,然后将其向后移植以供您使用。)

    【讨论】:

      【解决方案2】:

      This answer 在另一个问题上似乎对我有用。

      简而言之,创建一个自定义输入函数:

      def email_input(prompt=None):
          if prompt:
              sys.stderr.write(str(prompt))
          return raw_input()
      

      然后调用代码变成:

          user_email = email_input('Email: ')
          user_password = getpass('Password: ')
      

      这会导致电子邮件和密码提示都被发送到 stderr(打印到控制台),并且不会干扰重定向的日志输出。

      【讨论】:

        【解决方案3】:

        根据official documentation getpass([prompt[, stream]]) 有第二个可选参数,指示输出流以将提示打印到(默认为stderr)。

        当您重定向输出 (stdout) 时,对于 getpass,提示仍会打印到 stderr,但 raw_input 不支持设置输出流,因此其提示会重定向到目标文件。

        因此,要解决您的问题,您还必须将提示打印到stderr 以发送电子邮件。

        【讨论】:

          猜你喜欢
          • 2019-03-27
          • 1970-01-01
          • 2010-10-22
          • 1970-01-01
          • 2015-06-27
          • 1970-01-01
          • 2016-08-09
          • 2013-10-11
          • 2023-03-19
          相关资源
          最近更新 更多