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']也可以,但出于某种原因,星号不起作用..有什么想法吗?
答案 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
外,还请确保未引用您的路径。否则它将不会被外壳扩展。
如果路径中可能包含特殊字符,则必须手动对其进行转义。