我正在尝试通过调用cvs.exe进程从Python进行CVSlogin。 当手动调用cvs.exe时,会向控制台输出一条消息,然后等待用户input密码。
当用subprocess.Popen调用它时,我注意到了这个调用块。 代码是
subprocess.Popen(cvscmd, shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
我认为它阻塞,因为它正在等待input,但我的期望是,调用Popen将立即返回,然后我可以调用subprocess.communicate()input实际的密码。 我怎样才能做到这一点,并避免阻止Popen?
操作系统:Windows XP
Python:2.6
cvs.exe:1.11
shell=True
部分。 你的外壳与它无关。 使用shell=True
是麻烦的常见原因。 例:
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。
如果你正在自动化需要输入的外部程序 – 比如密码 – 你最好的办法就是使用pexpect 。