2009-02-09 7 views
3

Я запускаю установщик msi в бесшумном режиме и кэширует журналы в определенном файле. Ниже приведена команда, которую мне нужно выполнить.subprocess.Popen error

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% является неизвестным пользователю программой!

Есть 2 способа решения этой проблемы:

  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» должен быть r «C: \ Program Files \ My Installer \ Setup.exe». Их либо нужно удвоить, либо строка должна быть строкой r "". –

2

Проблема в том, что вы действительно поставляете Setup.exe только один аргумент. Не думайте в терминах оболочки, строка, которую вы передаете в качестве аргумента, больше не разделяется на пространства, это ваш долг!

Так что, если вы абсолютно уверены в том, что «/ дп/ЛВ% 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

+0

Котировки необходимы. Не знаю, почему. Даже переключатель v повторяется. I – kingpin

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] 

Является ли имя каталога действительно "Мой Installer" (с ведущее пространство)?

Также, как правило, вы должны использовать косые черты в спецификациях пути.Python должен обрабатывать их без проблем (даже в Windows), и вы избегаете каких-либо проблем с интерпретацией обратной косой черты python в качестве escape-символов.

(например:

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

)

+0

Нет ведущего пространства. – kingpin

+0

... тогда, если ваш код имеет ведущее пространство в пути, это очевидный источник ошибок. –

 Смежные вопросы

  • Нет связанных вопросов^_^