Python子进程到Bash:花括号

时间:2011-12-25 12:34:32

标签: python bash popen

我有以下Python行:

import subprocess
subprocess.Popen("egrep -r --exclude=*{.git,.svn}* \"text\" ~/directory", stdout=subprocess.PIPE, shell=True).communicate()[0]

不幸的是,bash完全忽略 - exclude = * {.git,.svn} * 标志。

我把问题缩小到花括号。 --exclude = * .git *将通过python的popen工作,但是引入花括号的那一刻,我无助了。有什么建议吗?

注意:我尝试使用Python的命令库运行命令,它产生完全相同的输出 - 并且完全相同的忽略--exclude标志。

4 个答案:

答案 0 :(得分:3)

当你传递shell = True时,python会将命令转换为/bin/sh -c <command>(如here所述)。 / bin / sh显然不支持花括号扩展。您可以尝试以下方法:

import subprocess
subprocess.Popen(["/bin/bash", "-c", "egrep -r --exclude=*{.git,.svn}* \"text\" ~/directory"], stdout=subprocess.PIPE).communicate()[0]

答案 1 :(得分:2)

我猜它可能是shell转义?

最好自己拆分参数,并完全避免使用shell?

import subprocess
subprocess.Popen(["egrep","-r","--exclude=*{.git,.svn}*","text","~/directory"], stdout=subprocess.PIPE).communicate()[0]

注意:您可能需要展开{​​{1}},我不确定。

或者如果bash应该扩展大括号,那么你可以在python中执行:

~

答案 2 :(得分:0)

您需要引用该表达式以防止bash在您关闭时针对当前工作目录对其进行评估。如果您正在寻找“文本”(带引号),那么您的搜索字词也会出现错误。你的转义会将引号引入Python字符串,但需要再次完成以使shell看到它们。

即。 ... --exclude='*{.git,.svn}*' \\\"text\\\" ...

答案 3 :(得分:0)

从Python Popen的角度来看,如果您在Python变量中捕获输出,那么您所做的就是可以工作的:

import subprocess
myOutput = subprocess.Popen("egrep -r --exclude=*{.git,.svn}* \"text\" ~/directory", stdout=subprocess.PIPE, shell=True).communicate()[0]
print "Output: ", myOutput

我已经在终端中测试了Bash作为默认的Shell命令,它运行良好。

请注意,'grep -E'应优先于'egrep',现已弃用。

你当然知道\也是Bash的逃脱角色,不是吗?我的意思是,'*'和花括号被Bash消耗,因此不会移交给grep。因此,你应该逃避它们。

grep -Er --exclude=\*\{.git,.svn\}\* \"text\" ~/directory