问题:
find
使用命令或替代方法打印满足以 shell 表达式表示的任意条件的文件(路径)集。
前任:有一个名为 ca.crt 的证书文件,其 OU(组织单位)可以是 openshift,以下表达式将返回状态代码 0(如果为 true),否则返回 0。
openssl x509 -in ca.crt -text -noout 2>/dev/null | grep "OU = openshift" > /dev/null
如何使用此表达式和命令find
来查找给定目录树下组织单位为“openshift”的所有证书文件?
我看过:
页面-exec
中的选项,其内容如下,find
man
-exec command ;
Execute command; true if 0 status is returned....
我不明白这个特定的声明:“如果返回 0 状态则为 true”。这是否意味着find
如果特定文件的命令执行返回 0 状态,则认为该文件匹配 (true`)?这对解决问题有什么用吗?
问题:
如果不编写 shell 脚本,最简单的方法是什么?一艘班轮将是理想的选择。
答案1
我们想要在这里做的是使用带有-exec
in 的管道find
作为测试,即类似
find /search/path -type f -name ca.crt -exec something {} \; -print
如果应打印路径名,则其中something
返回退出状态为零。
现在,我们不能find
直接使用管道,但我们可以让它调用sh -c
:
find /search/path -type f -name ca.crt -exec sh -c '
openssl x509 -in "$1" -text -noout 2>/dev/null |
grep -F -q "OU=openshift"' sh {} \; -print
这里发生的事情是find
调用一个内联sh -c
脚本来执行您的管道(我只做了轻微的更改)。如果管道以零退出状态退出(如果grep -q
在 的输出中找到文本模式,则会执行此操作openssl
),然后-print
生效,并ca.crt
打印具有该名称的常规文件的路径名。
文件的路径名ca.crt
作为 传递到内联脚本中$1
。
一般来说,您使用的大多数谓词find
是测试, 包括-exec
。如果一个测试通过对于特定的路径名,则考虑下一个测试。
在上面的命令中,测试是“该文件是常规文件吗?” ( -type f
),“它的名字是什么ca.crt
?” ( -name ca.crt
),“如果我现在运行此命令,并{}
替换为路径名,退出状态是否为零?” ( -exec ... \;
)。最后-print
的总是真的-print
,因此如果进行的话,之后的任何进一步测试都将始终进行。
sh -c
您可以通过一次为尽可能多的路径名调用脚本(而不是每个路径名一次)来使其效率稍微提高一些。然后,我们从内联脚本中打印路径名。
find /search/path -type f -name ca.crt -exec sh -c '
for pathname do
if openssl x509 -in "$pathname" -text -noout 2>/dev/null |
grep -F -q "OU=openshift"
then
printf "%s\n" "$pathname"
fi
done' sh {} +
这是如何正确地使用来自 的路径名提供循环find
。
有关的: