python 为什么当 args 是序列时 subprocess.Popen 不起作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2400878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:34:09  来源:igfitidea点击:

Why subprocess.Popen doesn't work when args is sequence?

pythonsubprocess

提问by mvladic

I'm having a problem with subprocess.Popen when args parameter is given as sequence.

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

For example:

例如:

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

This works (it prints the correct size of /home/support/Maildir dir):

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

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

But, this doesn't work (try it):

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

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

What's wrong?

怎么了?

回答by

From the documentation

文档

On Unix, with shell=True: […] If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself. That is to say, Popen does the equivalent of:

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

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

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

Which translates in your case to:

这在你的情况下转化为:

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

This means that -s, -band maildirare interpreted as options by the shell, not by du(try it on the shell commandline!).

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

Since shell=Trueis not needed in your case anyway, you could just remove it:

由于shell=True无论如何在您的情况下都不需要,您可以将其删除:

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

Alternatively you could just use your orignal approach, but you don't need a list in that case. You would also have to take care of spaces in the directory name:

或者,您可以只使用您的原始方法,但在这种情况下您不需要列表。您还必须注意目录名称中的空格:

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

回答by YOU

From document,

文档

On Unix, with shell=True: If args is a string, it specifies the command string to execute through the shell. If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional shell arguments.

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

So, Try

所以,试试

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

or

或者

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

回答by SilentGhost

it should be ["du", "-s", "-b", maildir]

它应该是 ["du", "-s", "-b", maildir]