生成期望控制台输入而不阻塞的子进程?
-
21-08-2019 - |
题
我正在尝试通过调用 cvs.exe 进程从 Python 进行 CVS 登录。当手动调用cvs.exe时,它会向控制台打印一条消息,然后等待用户输入密码。
当使用 subprocess.Popen 调用它时,我注意到调用被阻塞。代码是
subprocess.Popen(cvscmd, shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
我认为它会阻塞,因为它正在等待输入,但我的期望是调用 Popen 会立即返回,然后我可以调用 subprocess.communicate() 来输入实际密码。我怎样才能实现这种行为并避免阻塞 Popen?
操作系统:视窗XP
Python:2.6
CVS.exe:1.11
解决方案
- 去除
shell=True
部分。你的外壳与它无关。使用shell=True
是造成麻烦的常见原因。 - 使用 cmd 的参数列表。
例子:
cmd = ['cvs',
'-d:pserver:anonymous@bayonne.cvs.sourceforge.net:/cvsroot/bayonne',
'login']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
这不会在我的系统上阻塞(我的脚本继续执行)。然而,由于 cvs 直接从终端读取密码(而不是从标准输入或输出),您 不能 只需将密码写入子进程的标准输入即可。
您可以做的是将密码作为 CVSROOT 规范的一部分传递,如下所示:
:pserver:<user>[:<passwd>]@<server>:/<path>
IE。登录 Sourceforge 项目的函数:
import subprocess
def login_to_sourceforge_cvs(project, username='anonymous', password=''):
host = '%s.cvs.sourceforge.net' % project
path = '/cvsroot/%s' % project
cmd = ['cvs',
'-d:pserver:%s:%s@%s:%s' % (username, password, host, path),
'login']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE
stderr=subprocess.STDOUT)
return p
这对我有用。呼唤
login_to_sourceforge_cvs('bayonne')
将匿名登录到 bayonne 项目的 cvs。
其他提示
如果您是自动化需要输入外部程序 - 如密码 - 你最好的选择很可能是使用 Pexpect的。
不隶属于 StackOverflow