Python的subprocess.Popen()结果与命令行不同?

时间:2012-02-10 16:24:09

标签: python bash cygwin

在Windows 7 x32上使用Cygwin,在VS解决方案目录中,find命令会产生正确的结果:

$ find . -iname "*.sln"
./ProjName.sln

但与Python的subprocess.Popen()相同的命令似乎仅在*上匹配:

>>> import subprocess
>>> print subprocess.Popen(['find', '.', '-iname', '"*.sln"'],
...     stdout=subprocess.PIPE, shell=True).communicate()[0]
.
./.git
./.git/COMMIT_EDITMSG
./.git/config
./.git/description
<snip>

我的Popen()电话有什么问题?

3 个答案:

答案 0 :(得分:3)

以下适用于我:

>>> import subprocess
>>> print subprocess.Popen(['find', '.', '-iname', '*.sln'],
...     stdout=subprocess.PIPE, shell=False).communicate()[0]

请注意删除*.sln周围的双引号和shellFalse的设置。

这可确保*.sln逐字传递给find,并且不会被shell扩展。

编辑:以下内容也适用:

>>> print subprocess.Popen(['find . -iname "*.sln"'],
...     stdout=subprocess.PIPE, shell=True).communicate()[0]

答案 1 :(得分:2)

在POSIX系统上,当你使用Popen(['find', '.', '-iname', '"*.sln"'], shell=True)时,Python会这样做:

/bin/sh -c find . -iname "*.sln"

如果您阅读sh的文档,您会发现只有-c之后的第一个参数被视为要作为shell脚本执行的命令字符串。其余参数实际上被视为shell脚本的参数。在这种情况下,由于shell脚本仅包含命令名“find”,因此将忽略参数。如果您运行:

,您可以观察到此行为
>>> subprocess.call(['echo arg0 = $0, arg1 = $1', 'foo', 'bar'], shell=True)
arg0 = foo, arg1 = bar
0

答案 2 :(得分:0)

代码应为:

print subprocess.Popen(['find . -iname "*.sln"'], stdout=subprocess.PIPE, shell=True).communicate()[0]