Почему subprocess.Popen не работает, когда args является последовательностью? - PullRequest
7 голосов
/ 08 марта 2010

У меня проблема с подпроцессом. Открывается, когда параметр 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

Что не так?

Ответы [ 3 ]

11 голосов
/ 08 марта 2010

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

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

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]
5 голосов
/ 08 марта 2010

С документ ,

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

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

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

или

subprocess.Popen(["du","-s","-b",maildir], ...
1 голос
/ 08 марта 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...