2009-02-09 25 views
3

我正在靜默模式下運行msi安裝程序,並在特定文件中緩存日誌。以下是我需要執行的命令。subprocess.Popen錯誤

C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"

我用:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0] 

執行命令但它不能識別的操作並給出了關於選擇錯誤的選項錯誤。我已經交叉驗證並發現該命令僅以這種方式起作用。

回答

8

問題很微妙。

您正在直接執行程序。它得到:

argv[0] = "C:\Program Files\ My Installer\Setup.exe" 
argv[1] = /s /v "/qn /lv %TEMP%\log_silent.log" 

而應該是:

argv[1] = "/s" 
argv[2] = "/v" 
argv[3] = "/qn" 
argv[4] = "/lv %TEMP%\log_silent.log" 

換句話說,它應該接受5個參數,而不是2個參數。

此外,%TEMP%直接不知道程序!

有兩種方法來解決這個問題:

  1. 調用外殼。

    p = subprocess.Popen('C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"', shell=True) 
    output = p.communicate()[0] 
    
  2. 直接調用程序(更安全)

    s = ['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'] 
    safes = [os.path.expandvars(p) for p in argument_string] 
    p = subprocess.Popen(safes[0], safes[1:]) 
    output = p.communicate()[0] 
    
+1

另外,「C:\ Program Files \ My Installer \ Setup.exe」應該是「C:\ Program Files \ My Installer \ Setup.exe」。 \或者需要加倍,或者字符串需要是一個r「」字符串。 – 2009-02-09 00:52:36

2

問題是,您只有一個參數有效地提供Setup.exe。不要認爲在shell中,作爲參數交出的字符串不會在空間上分裂,這是您的責任!

所以,如果你是絕對肯定 「/ QN/LV%TEMP%\ log_silent.log」 應該是一個參數,然後使用此:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn /lv %TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0] 

否則(我想這將是一個正確的),使用此:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn', '/lv', '%TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0] 
+0

具有由空間分隔每個參數的幫助。 – kingpin 2009-02-12 00:48:24

+0

需要報價。不知道爲什麼。即使交換機v重複。 I – kingpin 2009-02-12 00:56:31

0

嘗試把每個參數在其自己的字符串(格式化的可讀性):

cmd = ['C:\Program Files\ My Installer\Setup.exe', 
     '/s', 
     '/v', 
     '"/qn', 
     '/lv', 
     '%TEMP%\log_silent.log"'] 

subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0] 

雖然我不得不說,那些雙引號沒有在正確的地方看我。

0

你說:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0] 

是目錄名真正的 「我的安裝程序」(用領先的空間)?

此外,作爲一般規則,您應該在路徑規範中使用正斜槓。Python應該可以無縫地處理它們(甚至在Windows中),並且避免python將反斜槓解釋爲轉義字符的問題。

(例如:

>>> s = 'c:\program files\norton antivirus' 
>>> print s 
c:\program files 
orton antivirus