Почему подпроцесс. Popen не работает, когда args является последовательностью?

У меня есть проблема с подпроцессом. Popen, когда args параметр дан как последовательность.

Например:

import subprocess
maildir = "/home/support/Maildir"

Это работает (это печатает корректный размер/home/support/Maildir dir):

size = subprocess.Popen(["du -s -b " + maildir], shell=True,
                        stdout=subprocess.PIPE).communicate()[0].split()[0]
print size

Но, это не работает (попробуйте его):

size = subprocess.Popen(["du", "-s -b", maildir], shell=True,
                        stdout=subprocess.PIPE).communicate()[0].split()[0]
print size

Что случилось?

7
задан mvladic 9 March 2010 в 19:14
поделиться

3 ответа

Из документации

На Unix, с shell=True: [...] Если args - последовательность, первый элемент задает строку команды, а все дополнительные элементы будут рассматриваться как дополнительные аргументы. командную строку, а любые дополнительные элементы будут рассматриваться как дополнительные аргументы к самой оболочки. То есть, Popen делает эквивалент:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

Что в вашем случае означает:

Popen(['/bin/sh', '-c', 'du', '-s', '-b', maildir])

Это означает, что -s, -b и maildir интерпретируются как опции оболочкой, а не du (попробуйте это сделать в командной строке оболочки!).

Поскольку shell=True в вашем случае все равно не нужен, вы можете просто удалить его:

size = subprocess.Popen(['du', '-s', '-b', maildir],
                    stdout=subprocess.PIPE).communicate()[0].split()[0]

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

size = subprocess.Popen('du -s -b "%s"' % maildir, shell=True,
                    stdout=subprocess.PIPE).communicate()[0].split()[0]
11
ответ дан 6 December 2019 в 11:48
поделиться

это должно быть ["du", "-s", "-b", maildir]

1
ответ дан 6 December 2019 в 11:48
поделиться

Из документа ,

В Unix с shell = True : Если args является {{ 1}} строка , она определяет строку команды для выполнения через оболочку. Если args представляет собой последовательность , первый элемент {{1 }} задает командную строку, и любые дополнительные элементы будут рассматриваться как дополнительные аргументы оболочки.

Итак, попробуйте

subprocess.Popen("du -s -b " + maildir, ...

или

subprocess.Popen(["du","-s","-b",maildir], ...
5
ответ дан 6 December 2019 в 11:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: