Подтвердить что ты не робот

Использование подстановок подпроцесса Python

import os

import subprocess

proc = subprocess.Popen(['ls','*.bc'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

out,err = proc.communicate()

print out

Этот script должен печатать все файлы с расширением .bc, но возвращает пустой список. Если я выполняю ls *.bc вручную в командной строке, он работает. Выполнение ['ls', 'test.bc'] внутри script работает, но по какой-то причине символ звезды не работает. Любые идеи?

4b9b3361

Ответ 1

Вам нужно предоставить shell=True, чтобы выполнить команду через интерпретатор оболочки. Если вы это сделаете, вы больше не сможете предоставлять список в качестве первого аргумента, потому что тогда будут переданы аргументы. Вместо этого укажите необработанную командную строку, как вы хотите, чтобы она была передана в оболочку:

 proc = subprocess.Popen('ls *.bc', shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)

Ответ 2

Расширение * glob является частью оболочки, но по умолчанию subprocess не отправляет ваши команды через оболочку, поэтому выполняется команда (первый аргумент, ls), а затем литерал * используется как аргумент.

Это хорошо, см. блок предупреждения в разделе "Часто используемые аргументы" в документах подпроцесса. Он в основном обсуждает последствия для безопасности, но также помогает избежать глупых ошибок программирования (так как нет волшебных символов оболочки, о которых нужно беспокоиться)

Моя основная жалоба с shell=True заключается в том, что обычно существует лучший способ решить проблему - с вашим примером вы должны использовать the glob модуль:

import glob
files = glob.glob("*.bc")
print files # ['file1.bc', 'file2.bc']

Это будет быстрее (без дополнительных затрат на запуск), более надежной и кросс-платформенной (не зависит от платформы, имеющей команду ls)