2012-02-10 112 views
1

在Windows 7 X32使用Cygwin,在VS解决方案目录,find命令将产生正确的结果:Python的subprocess.Popen()结果与命令行不同?

$ 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

对我来说,以下工作:

>>> 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] 
+0

我删除了我的第一条评论。 'shlex.split()'将移除模式周围的引号,但我仍然不确定为什么'shell = True'会导致完全匹配。 – wes 2012-02-10 16:37:02

+0

@wes:我一直在进一步尝试,看起来'shell = True'需要将命令指定为单个参数。看到我更新的答案。 – NPE 2012-02-10 16:39:38

+0

啊,是的,我现在在文档中看到了。谢谢。 – wes 2012-02-10 16:42:11

0

的代码应该是:

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

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

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

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

>>> subprocess.call(['echo arg0 = $0, arg1 = $1', 'foo', 'bar'], shell=True) 
arg0 = foo, arg1 = bar 
0 
相关问题