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

mvl*_*dic 7 python subprocess

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

例如:

import subprocess
maildir = "/home/support/Maildir"
Run Code Online (Sandbox Code Playgroud)

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

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

但是,这不起作用(尝试):

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

怎么了?

小智 11

文档中

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

Popen(['/bin/sh', '-c', args[0], args[1], ...])
Run Code Online (Sandbox Code Playgroud)

在您的情况下翻译为:

Popen(['/bin/sh', '-c', 'du', '-s', '-b', maildir])
Run Code Online (Sandbox Code Playgroud)

这意味着-s,-b并且maildir被shell解释为选项,而不是du(在shell命令行上尝试它!).

既然shell=True你的情况不需要,你可以删除它:

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

或者,您可以使用您的原始方法,但在这种情况下您不需要列表.您还需要处理目录名称中的空格:

size = subprocess.Popen('du -s -b "%s"' % maildir, shell=True,
                    stdout=subprocess.PIPE).communicate()[0].split()[0]
Run Code Online (Sandbox Code Playgroud)


YOU*_*YOU 5

文件,

在Unix上,shell = True:如果args是一个 字符串,它指定要通过shell执行的命令字符串.如果args是一个序列,则第一个项指定命令字符串,任何其他项将被视为附加的shell参数.

所以,试试吧

subprocess.Popen("du -s -b " + maildir, ...
Run Code Online (Sandbox Code Playgroud)

要么

subprocess.Popen(["du","-s","-b",maildir], ...
Run Code Online (Sandbox Code Playgroud)