简体   繁体   English

Python - 使用Popen执行具有多个条件的查找

[英]Python - execute find with multiple conditions using Popen

I'd like to execute find with multiple conditions, for example: find foo excluding hidden files: 我想用多个条件执行find ,例如:find foo不包括隐藏文件:

find . -type f \( -iname '*foo*' ! -name '.*' \)

Python code: 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()

Can somebody explain what I'm missing? 有人可以解释我错过的东西吗? Thanks! 谢谢!

I ran into this issue as well, and I'm sure you've figured this out by now but I figured I'd weigh in just in case anyone else runs into the same issue. 我也遇到了这个问题,我相信你现在已经想到了这个问题,但我想我会考虑以防万一其他人遇到同样的问题。 Come to find out, this happens due to what Python is actually doing when you use Popen (When shell=True is used, python is basically just using /bin/sh -c to pass in your command ( Python's subprocess.Popen() results differ from command line? ). shell is False by default, so if you omit this or set it to False, whatever is specified in 'executable' will be used. The docs go into more detail here: https://docs.python.org/2/library/subprocess.html#subprocess.Popen 来发现,这是因为当你使用Popen时Python正在做什么(当使用shell = True时,python基本上只是使用/ bin / sh -c传递你的命令( Python的subprocess.Popen()结果)与命令行不同? )。默认情况下shell为False,所以如果你省略它或将其设置为False,将使用'executable'中指定的任何内容。这里的文档更详细: https://docs.python .ORG / 2 /库/ subprocess.html#subprocess.Popen

Something along these lines should work 这些方面的东西应该有效

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()

In python 3.7 subprocess.run() you can drop splitting cmd on spaces into a list, string will do just fine. 在python 3.7 subprocess.run()中,您可以将空格上的cmd拆分为一个列表,字符串就可以了。

Nothing in the documentation though subrocess.run() . 通过subrocess.run()在文档中没有任何内容。

I was unable to get a command expanded into a list to work, while the string worked fine. 我无法将扩展到列表的命令工作,而字符串工作正常。

cmd = "find . -type f -iname \*foo\* ! -name .\\*"
print(cmd)
ret = subprocess.run(cmd, shell=True, capture_output=True)
print(ret)

Testing: 测试:

$ 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'')

at least, need to escape the *'s there. 至少,需要逃避那里的*。

at second either escape the ( and ) by backslash (pass the "\\\\(" and "\\\\)" to shell) 在第二个或者通过反斜杠转义(和)(将“\\\\(”和“\\\\)”传递给shell)

cmd = ["find", ".", "-type", "f", "\\(", "-iname", "\\*foo\\*", "!", "-name", ".\\*", "\\)"]

or even just get rid of those ( and ) - 甚至只是摆脱那些(和) -

cmd = ["find", ".", "-type", "f", "-iname", "\\*foo\\*", "!", "-name", ".\\*"]

should work just fine 应该工作得很好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM