4

我正在尝试通过调用 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?

操作系统:Windows XP
Python:2.6
cvs.exe:1.11

4

2 回答 2

2
  • 拆下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>

即登录到 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。

于 2009-02-04T11:00:35.707 回答
0

如果您正在自动化需要输入(如密码)的外部程序,那么您最好的选择可能是使用pexpect

于 2009-02-04T21:50:13.540 回答