Python - 使用Popen执行带多个条件的查找
我想用多个条件来执行 find
命令,比如:查找foo,但不包括隐藏文件:
find . -type f \( -iname '*foo*' ! -name '.*' \)
Python 代码:
import subprocess
cmd = ["find", ".", "-type", "f", "(", "-iname", "*foo*", "!", "-name", ".*", ")"]
sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print sp.communicate()[0].split()
有人能告诉我我漏掉了什么吗?谢谢!
3 个回答
-1
至少需要把那里的 * 符号进行转义。
其次,要么用反斜杠来转义 ( 和 ),也就是在命令行中输入 "\\(" 和 "\\)"。
cmd = ["find", ".", "-type", "f", "\\(", "-iname", "\\*foo\\*", "!", "-name", ".\\*", "\\)"]
要么干脆把这些 ( 和 ) 去掉 -
cmd = ["find", ".", "-type", "f", "-iname", "\\*foo\\*", "!", "-name", ".\\*"]
这样应该就能正常工作了。
0
在Python 3.7的subprocess.run()中,你可以直接用字符串来代替把命令按空格分割成列表,这样也能正常工作。
不过在文档里并没有说明这一点,具体可以查看subprocess.run()。
我发现把命令展开成列表的方式不太好用,而直接用字符串就没问题。
cmd = "find . -type f -iname \*foo\* ! -name .\\*"
print(cmd)
ret = subprocess.run(cmd, shell=True, capture_output=True)
print(ret)
测试:
$ find . -type f -iname \*foo\* ! -name .\*
./foobar.txt
./barfoo.txt
$ ./findfoo.py
find . -type f -iname \*foo\* ! -name .\*
CompletedProcess(args='find . -type f -iname \\*foo\\* ! -name .\\*',
returncode=0, stdout=b'./foobar.txt\n./barfoo.txt\n', stderr=b'')
1
我也遇到过这个问题,我相信你现在已经搞清楚了,但我还是想说一下,以防其他人也碰到同样的问题。其实,这个问题的原因是因为当你使用Popen时,Python内部是怎么处理的(当你设置shell=True时,Python基本上是通过/bin/sh -c来执行你的命令,具体可以参考这个链接:Python的subprocess.Popen()结果与命令行不同?)。默认情况下,shell是False,所以如果你不写这个或者把它设置为False,那么在'executable'中指定的内容就会被使用。文档中对此有更详细的说明,可以查看这里:https://docs.python.org/2/library/subprocess.html#subprocess.Popen
类似这样的代码应该可以工作
import subprocess
cmd = 'find . -type f -iname "*foo*" ! -name ".*"'
sp = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print sp.communicate()[0].split()