windows 生成期望控制台输入而不阻塞的子进程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/510751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spawn subprocess that expects console input without blocking?
提问by rpg
I am trying to do a CVS login from Python by calling the cvs.exe process. When calling cvs.exe by hand, it prints a message to the console and then waits for the user to input the password.
我正在尝试通过调用 cvs.exe 进程从 Python 进行 CVS 登录。当手动调用 cvs.exe 时,它会向控制台打印一条消息,然后等待用户输入密码。
When calling it with subprocess.Popen, I've noticed that the call blocks. The code is
当用 subprocess.Popen 调用它时,我注意到调用块。代码是
subprocess.Popen(cvscmd, shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
I assume that it blocks because it's waiting for input, but my expectation was that calling Popen would return immediately and then I could call subprocess.communicate() to input the actual password. How can I achieve this behaviour and avoid blocking on Popen?
我假设它阻塞是因为它在等待输入,但我的期望是调用 Popen 会立即返回,然后我可以调用 subprocess.communicate() 来输入实际密码。我怎样才能实现这种行为并避免在 Popen 上阻塞?
OS: Windows XP
Python: 2.6
cvs.exe: 1.11
操作系统:Windows XP
Python:2.6
cvs.exe:1.11
采纳答案by nosklo
- Remove the
shell=True
part. Your shell has nothing to do with it. Usingshell=True
is a common cause of trouble. - Use a list of parameters for cmd.
- 取下
shell=True
零件。你的外壳与它无关。使用shell=True
是造成问题的常见原因。 - 使用 cmd 的参数列表。
Example:
例子:
cmd = ['cvs',
'-d:pserver:[email protected]:/cvsroot/bayonne',
'login']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
This won't block on my system (my script continues executing). However since cvs reads the password directly from the terminal (not from standard input or output) you can'tjust write the password to the subprocess' stdin.
这不会在我的系统上阻塞(我的脚本继续执行)。然而,由于 cvs 直接从终端(而不是从标准输入或输出)读取密码,您不能只将密码写入子进程的标准输入。
What you could do is pass the password as part of the CVSROOT specification instead, like this:
您可以做的是将密码作为 CVSROOT 规范的一部分传递,如下所示:
:pserver:<user>[:<passwd>]@<server>:/<path>
I.e. a function to login to a sourceforge project:
即登录 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
This works for me. Calling
这对我有用。打电话
login_to_sourceforge_cvs('bayonne')
Will log in anonymously to the bayonne project's cvs.
会匿名登录bayonne项目的cvs。