2012-02-10 2 views
1

Использование Cygwin на Windows 7 x32, в каталоге решения VS, команда find производит правильные результаты:Результаты подпроцесса Python.Popen() отличаются от командной строки?

$ find . -iname "*.sln" 
./ProjName.sln 

но та же команда с Питона subprocess.Popen(), кажется, соответствие на * в одиночку:

>>> import subprocess 
>>> print subprocess.Popen(['find', '.', '-iname', '"*.sln"'], 
...  stdout=subprocess.PIPE, shell=True).communicate()[0] 
. 
./.git 
./.git/COMMIT_EDITMSG 
./.git/config 
./.git/description 
<snip> 

Что случилось с моим звонком Popen()?

ответ

3

следующие работы для меня:

>>> import subprocess 
>>> print subprocess.Popen(['find', '.', '-iname', '*.sln'], 
...  stdout=subprocess.PIPE, shell=False).communicate()[0] 

Примечание удаление двойных кавычек вокруг *.sln и установка shell к False.

Это гарантирует, что *.sln передается до find дословно и не расшифровывается оболочкой.

редактировать: Ниже также работает:

>>> print subprocess.Popen(['find . -iname "*.sln"'], 
...  stdout=subprocess.PIPE, shell=True).communicate()[0] 
+0

Я удалил свой первый комментарий. 'shlex.split()' удалит кавычки вокруг шаблона, но я все еще не уверен, почему 'shell = True' вызывает полное совпадение. – wes

+0

@wes: Я экспериментировал с этим дальше, и кажется, что 'shell = True' требует, чтобы команда была указана как один аргумент. См. Мой обновленный ответ. – NPE

+0

Ах да, я вижу это в документах сейчас. Благодарю. – wes

0

Код должен быть:

print subprocess.Popen(['find . -iname "*.sln"'], stdout=subprocess.PIPE, shell=True).communicate()[0] 
2

В системах POSIX, при использовании Popen(['find', '.', '-iname', '"*.sln"'], shell=True), Python делает это:

/bin/sh -c find . -iname "*.sln" 

Если вы прочитали документацию для sh, вы обнаружите, что только первый аргумент после -c рассматривается как командная строка, которая должна исполняться как сценарий оболочки. Остальные аргументы фактически рассматриваются как аргументы сценарию оболочки. В этом случае, поскольку сценарий оболочки состоит исключительно из имени команды «find», аргументы игнорируются. Такое поведение можно наблюдать, если вы запустите:

>>> subprocess.call(['echo arg0 = $0, arg1 = $1', 'foo', 'bar'], shell=True) 
arg0 = foo, arg1 = bar 
0 
Смежные вопросы