我有以下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标志。
答案 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