这个问题困扰了我一个星期。我需要安全地通过 subprocess 提交来自用户输入的密码,因为我试图避免引入命令注入漏洞。以下是我如何在同事的帮助下解决该问题的方法。
import subprocess
command = ['command', 'option1', '--password']
subprocess.Popen(command, stdin=subprocess.PIPE).wait(timeout=60)
最重要的组件是 .wait(timeout=int),因为它允许用户向 stdin 提供输入。否则,超时默认为 0,不给用户时间输入,导致返回 None 或 null 字符串。我花了很长时间才弄清楚这一点。
如果你知道自己要多次使用此功能,可以覆盖 popen 函数并将其用作私有方法,据同一程序员告知,如果你预计其他人会对代码进行维护并且不想让他们乱改,这是最佳实践。
def _popen(cmd):
proc_h = subprocess.Popen(cmd, stdin=subprocess.PIPE)
proc_h.wait(timeout=60)
return proc_h.poll() == os.EX_OK
如果用户将被提示输入,则删除stdout=subprocess.PIPE非常重要。否则,进程似乎会挂起60秒,用户不会得到提示,也不会意识到他们需要提供密码。stdout将自然地进入shell窗口,并允许用户向popen()传递输入。
此外,只是为了解释为什么返回proc_h.poll() == os.EX_OK,因为它在命令成功时返回0。这只是C风格的最佳实践,用于在函数失败时返回系统错误代码,同时考虑到return 0将被解释器视为“false”。