Python子进程通配符用法

时间:2012-04-03 15:58:44

标签: python subprocess wildcard

import os

import subprocess

proc = subprocess.Popen(['ls','*.bc'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

out,err = proc.communicate()

print out

此脚本应打印带有.bc后缀的所有文件,但它会返回一个空列表。如果我在命令行中手动执行ls * .bc它可以工作。在脚本中执行['ls','test.bc']也可以,但出于某种原因,星号不起作用..有什么想法吗?

3 个答案:

答案 0 :(得分:63)

您需要提供shell=True以通过shell解释器执行命令。 但是,如果这样做,则不能再提供列表作为第一个参数,因为参数将被引用。而是根据您希望将原始命令行传递给shell来指定原始命令行:

 proc = subprocess.Popen('ls *.bc', shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)

答案 1 :(得分:52)

扩展* glob是shell的一部分,但默认情况下subprocess 通过shell发送命令,所以命令(第一个参数,{{执行1}}),然后使用文字ls作为参数。

这是一个好事,请参阅子进程文档的the warning block in the "Frequently Used Arguments" section。它主要讨论安全问题,但也可以帮助避免愚蠢的编程错误(因为没有魔术shell字符需要担心)

我对*的主要抱怨是,它通常意味着有更好的方法解决问题 - 您的示例应该使用the glob module

shell=True

这将更快(没有进程启动开销),更可靠和跨平台(不依赖于具有import glob files = glob.glob("*.bc") print files # ['file1.bc', 'file2.bc'] 命令的平台)

答案 2 :(得分:0)

除了执行shell=True外,还请确保未引用您的路径。否则它将不会被外壳扩展。

如果路径中可能包含特殊字符,则必须手动对其进行转义。