当执行类似 的搜索时,在 find 命令之后find -type d
添加 -参数会导致搜索返回比没有它更多的结果。print0
find -print0 -type d
答案1
如果您了解shell 中的&&
and运算符(以及 C、C++ 和衍生语言中的),那么您就了解了.||
-a
-o
find
刷新你的记忆:
在壳里,
命令1 && 命令2
运行command1
,并且,如果它(command1
) 成功,它(shell)运行command2
。
命令1 || 命令2
运行command1
,并且,如果它(command1
) 失败,它(shell)运行command2
。
在可编译语言中,
表达式1 && 表达式2
评估expr1
。如果它 (expr1
) 计算结果为 false(零),它返回该值作为整个表达式的值。否则(如果expr1
评估为真(非零)值),它评估expr2
并将其作为整体表达式的值返回。
表达式1 || 表达式2
评估expr1
。如果它 (expr1
) 求值为真(非零)值,它返回该值作为整个表达式的值。否则(如果expr1
计算结果为 false(零))expr2
并将其作为整体表达式的值返回。
这称为“短路求值”,因为它允许对布尔表达式求值,而无需求值不需要确定表达式总值的项。
引用自查找(1),
GNUfind
根据优先级规则(参见运算符部分)从左到右计算给定的表达式,搜索以每个给定文件名为根的目录树,直到知道结果(左侧为 false)和操作,适用于或者),此时find
移至下一个文件名。
⋮
表达方式
该表达式由...测试(返回 true 或 false 值)和操作(具有副作用并返回 true 或 false 值)组成,所有这些都由运算符分隔。 -和假设省略了运算符。
⋮
⋮该小节关于行动指出-打印与
大多数操作一样,始终返回 true 值。运营商
⋮
表达式1 表达式2
表达式1-A表达式2
表达式1-和表达式2 ·······················································································································································································不符合 POSIX 标准和;表达式2不评估如果表达式1是假的。
表达式1-o表达式2
表达式1-或者表达式2 ································································································································································································不符合 POSIX 标准或者;表达式2不评估如果表达式1是真的。
这开放组规范find
有类似的话要说:
这寻找实用程序应递归地沿目录层次结构下降……,对遇到的每个文件的操作数部分中描述的主要元素组成的布尔表达式进行评估。
⋮
操作数
⋮
-打印初级应始终评估为真;它将导致当前路径名被写入标准输出。
⋮
可以使用以下运算符组合原色(按优先级递减的顺序):
⋮
表达 [-A] 表达初选的结合; AND 运算符由两个原色的并置隐含或由可选的显式表示-A操作员。如果第一个表达式为 false,则不应计算第二个表达式。
表达 -o 表达初选交替;或运算符。如果第一个表达式为 true,则不应计算第二个表达式。
两份文件都说:“如果没有表达存在,-打印应该被用作表达方式。”
---------------- 长话短说 ----------------
所以,
find -type d
相当于
find -type d -print
这相当于
find -type d -a -print
意思是,
- 对于每个文件,
- 评估
-type d
测试。 - 如果为真(即,如果当前“文件”是目录),则评估(执行)该
-print
操作。
- 评估
然而,
find -print -type d
相当于
find -print -a -type d
意思是,
- 对于每个文件,
- 评估(执行)
-print
行动 (即,这种情况发生对于所有文件)。 - 如果为真(总是
-print
如此),则评估-type d
测试。 - 而且,由于这是命令的结尾,因此测试结果
-type d
将被忽略。
- 评估(执行)
所以你有它。
答案2
查找参数的顺序很重要。该命令需要按如下方式构建find -type d -print0
,然后它将按预期工作。我只是想我会发布这个以防它对任何人有帮助。
答案3
理解命令的技巧find
是递归地评估前两个表达式/动作并将其分组为结果逻辑值的适当表达式(-true
或-false
),考虑到每对表达式/动作的评估是短路的(因此表达式/动作为如果第一个求值表达式是 ,则比较的第二个操作数AND
将不会被求值/求值和执行,并且如果第一个求值表达式是) 并且FALSE
表达式/动作作为比较的第二个操作数OR
将不会被求值/求值和执行TRUE
过程中遇到的每个动作将始终根据TRUE
先前评估的逻辑值(并且在评估时已减少为一个-true
或-false
表达式)一对表达式/动作。
扩展一个有用的例子关联1_CR 发布:
find . -false -o -false -a -printf 'nope\n' -o -printf 'yep\n' -o -printf 'nope\n'
yep
-false -o -false
:第一个操作数是一个表达式,因此不执行任何操作,其值为FALSE
;评估不是短路的,因为<expr1>
是FALSE
,所以-false
评估,其值为FALSE
;整个表达式的值为FALSE
,并且它被简化为一个-false
表达式,该表达式将使用以下表达式/操作进行评估;-false -a -printf 'nope\n'
:第一个操作数是一个表达式,因此不执行任何操作,其值为FALSE
;评估是短路的,因为<expr1>
是FALSE
,所以<expr2>
不评估也不执行;整个表达式的值为FALSE
,并且它被简化为一个-false
表达式,该表达式将使用以下表达式/操作进行评估;-false -o -printf 'yep\n'
:第一个操作数是一个表达式,因此不执行任何操作,其值为FALSE
;评估不是短路的,因为<expr1>
是FALSE
,所以printf 'yep\n'
立即评估并执行,其值为TRUE
;整个表达式的值为TRUE
,并且它被简化为一个-true
表达式,该表达式将使用以下表达式/操作进行评估;-true -o -printf 'nope\n'
:第一个操作数是一个表达式,因此不执行任何操作,其值为TRUE
;评估是短路的,因为<expr1>
是TRUE
,所以<expr2>
不评估也不执行;整个表达式的值为TRUE
;
对 执行相同的操作find [...] -print0 -type d
,它扩展为find [...] -print0 -a -type d
(因为缺少的运算符扩展为AND
运算符):
-print0 -a -type d
:第一个操作数是一个动作,所以-print0
立即评估并执行,其值为TRUE
;求值不是短路的,因为<expr1>
是TRUE
,所以-type d
求值,其值为TRUE
或FALSE
;整个表达式的值是TRUE
或FALSE
基于-type d
测试结果;