errore di subprocess.Popen
-
22-08-2019 - |
Domanda
Sono in esecuzione di un programma di installazione MSI in eventi del modo e caching silenziosi nel file specifico. Quanto segue è il comando che ho bisogno per eseguire.
C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"
ho usato:
subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0]
per eseguire il comando tuttavia non riconosce l'operazione e dà errore opzione sbagliata selezionata. Ho incrociato verificato e scoperto che il comando funziona solo in questo modo.
Soluzione
Il problema è molto sottile.
Si sta eseguendo direttamente il programma. Si ottiene:
argv[0] = "C:\Program Files\ My Installer\Setup.exe"
argv[1] = /s /v "/qn /lv %TEMP%\log_silent.log"
considerando che dovrebbe essere:
argv[1] = "/s"
argv[2] = "/v"
argv[3] = "/qn"
argv[4] = "/lv %TEMP%\log_silent.log"
In altre parole, si dovrebbe ricevere 5 argomenti, non 2 argomenti.
Inoltre, %TEMP%
è direttamente sconosciuto al programma!
Ci sono 2 modi per risolvere questo problema:
-
Chiamare il guscio.
p = subprocess.Popen('C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"', shell=True) output = p.communicate()[0]
-
Direttamente chiamata del programma (più sicuro)
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]
Altri suggerimenti
Il problema è che si fornisce in modo efficace Setup.exe con un solo argomento. Non pensare in termini di guscio, la stringa di consegnare come un argomento non viene a spacco su spazi più, questo è il tuo dovere!
Quindi, se si è assolutamente sicuri che "/ qn / lv% temp% \ log_silent.log" dovrebbe essere un argomento, quindi utilizzare questo:
subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn /lv %TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0]
In caso contrario (immagino che questo sarà corretto), utilizzare questo:
subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn', '/lv', '%TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0]
Prova a mettere ogni argomento nella propria stringa (riformattato per migliorare la leggibilità):
cmd = ['C:\Program Files\ My Installer\Setup.exe',
'/s',
'/v',
'"/qn',
'/lv',
'%TEMP%\log_silent.log"']
subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
Devo dire, però, quelle virgolette non cercare nei posti giusti per me.
Hai detto:
subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0]
è il nome della directory davvero "My Installer" (con uno spazio iniziale)?
Inoltre, come regola generale, è consigliabile utilizzare le barre nelle specifiche di percorso. Python dovrebbe gestirli senza problemi (anche su Windows) e evitare qualsiasi problema con Python interpretare backslash come caratteri di escape.
(ad esempio:
>>> s = 'c:\program files\norton antivirus'
>>> print s
c:\program files
orton antivirus
)