2009-02-04 42 views
4

我想通過調用cvs.exe進程從Python執行CVS登錄。 手動調用cvs.exe時,會向控制檯輸出消息,然後等待用戶輸入密碼。希望控制檯輸入沒有阻塞的Spawn子進程?

當用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

回答

2
  • 取出shell=True部分。你的外殼與它無關。使用shell=True是導致故障的常見原因。
  • 使用cmd的參數列表。

例子:

cmd = ['cvs', 
     '-d:pserver:[email protected]:/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:%[email protected]%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。

+0

密碼作爲CVSROOT的一部分似乎是一個更好的主意,但傳遞密碼使得cvs.exe認爲用戶名實際上是「user:password」! 例如:在命令行中鍵入cvs -d:pserver:user:pass @ server:path嘗試登錄「user:pass」並且仍然要求輸入密碼 – rpg 2009-02-04 12:14:46

+0

@Razvan:我的CVS版本似乎像我說的那樣工作。也許你有一個修改版本?你從哪裏得到你的CVS?你能升級嗎?你有沒有嘗試過我的示例代碼? – nosklo 2009-02-04 12:32:09

0

如果您要自動執行需要輸入的外部程序 - 比如密碼 - 您最好的選擇可能是使用pexpect