2014-09-03 7 views
1

У меня есть простой скрипт Python:Подпроцесс python.Popen принимает пространство в пути?

log("Running command: " + str(cmd)) 
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, close_fds=close_fds) 

Я выполняющийся его на Windows, на том же питона версии 2.6.1, но на разных виртуальных машинах. Один из них - Windows Server 2008 Enterprise, второй - Windows Server Enterprise, и я получил ошибку на только один из них.

Бревно с Windows Server Enterprise:

Running command: C:\Program File\MyProgram\program.exe "parameters" 
Error: 'C:\\Program' is not recognized as an internal or external command 

Бревна с Windows Server 2008 Enterprise:

Running command: C:\Program File\MyProgram\program.exe "parameters" 
... 

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

+0

Связанные/тождественны http://stackoverflow.com/questions/804995/how-to-use-subprocess-when-multiple -arguments-contains-spaces – beroe

+0

- это cmd строка или список строк? – tdelaney

+0

@beroe похоже, но не то же самое. В моем случае у меня есть только один код, который работает по-другому, иногда он может обрабатывать путь с пробелами, иногда нет, я пытаюсь понять, почему. – erkfel

ответ

3

Пути с пробелами должны быть экранированы. Самый простой способ сделать это, чтобы настроить команду в виде списка, добавьте оболочки = True и пусть питона сделать побег для вас:

import subprocess 
cmd = [r"C:\Program File\MyProgram\program.exe", "param1", "param2"] 
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE,stdin=subprocess.PIPE, close_fds=close_fds) 
+0

Спасибо за ответ, но это не ответ на мой вопрос. Мой вопрос: почему одна и та же часть кода работает по-разному на той же версии Python на почти той же Windows и как это возможно, что subprocess.Popen может обрабатывать неэкранированный путь с пробелами. Он должен быть экранирован, но это не так, и этот код работает, мне интересно, почему. – erkfel

+0

Использование 'shell = True' является ошибкой (stderr вызывает зависание) и небезопасно, поэтому не рекомендуется. –

+2

@ AlexanderTronchin-James - buggy? Если _shell = True_ вызывает зависания, это первое, что я слышал об этом. _shell = True_ действительно запускает риск инъекции команд, поэтому его использование не рекомендуется везде, но во многих случаях это разумно используется. Например, система сборки. – tdelaney

0

Рассмотрим это:

command = "C:\Path argument\or\path" 

Как различать между исполняемый файл C:\Path с аргументом argument\or\path и командой path, расположенной по адресу C:\Path\ argument\or? Если вы передадите список вместо строки в Popen однако, цель однозначна:

command = ["C:\Path argument\or\path"] 
proc = Popen(command, ...) 
+0

Joel, спасибо за ответ, но это не ответ на вопрос, пожалуйста, см. Мой комментарий к @tdelaney – erkfel