为什么subgs.Popen在args是序列时不起作用?

时间:2010-03-08 11:24:23

标签: python subprocess

我遇到subprocess.Popen的问题,当args参数作为序列给出时。

例如:

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

这可行(它打印正确大小的/ home / support / Maildir目录):

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 个答案:

答案 0 :(得分:11)

来自documentation

  

在Unix上,shell = True:[...]如果args是序列,则第一项指定   命令字符串,任何附加项将被视为附加参数   shell本身。也就是说,Popen相当于:

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

根据您的情况将其翻译为:

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

这意味着-s-bmaildir被shell解释为选项,而不是du(在shell命令行上尝试!)。

由于您的案例中不需要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]

答案 1 :(得分:5)

来自document

  

在Unix上, shell = True :如果args是a   字符串,它指定命令   要通过shell执行的字符串。   如果args是序列,则为第一项   指定命令字符串,以及任何   其他项目将被视为   额外的shell参数。

所以,试试

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

subprocess.Popen(["du","-s","-b",maildir], ...

答案 2 :(得分:1)

应为["du", "-s", "-b", maildir]