subprocess.Popen error - PullRequest
       8

subprocess.Popen error

3 голосов
/ 09 февраля 2009

Я запускаю установщик MSI в режиме без вывода сообщений и кэширую логи в конкретном файле. Вот команда, которую мне нужно выполнить.

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]

для выполнения команды, однако она не распознает операцию и выдает ошибку, касающуюся неправильной выбранной опции Я провел перекрестную проверку и обнаружил, что команда работает только таким образом.

Ответы [ 4 ]

8 голосов
/ 09 февраля 2009

Проблема очень тонкая.

Вы выполняете программу напрямую. Получается:

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]
    
2 голосов
/ 09 февраля 2009

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

Итак, если вы абсолютно уверены, что "/ 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 голосов
/ 09 февраля 2009

Вы сказали:

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

Действительно ли имя каталога "Мой установщик" (с начальным пробелом)?

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

(например:

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

)

0 голосов
/ 09 февраля 2009

Попробуйте поместить каждый аргумент в отдельную строку (переформатирован для удобства чтения):

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

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

Я должен сказать, что эти двойные кавычки не выглядят мне в нужных местах.

...