我无法破译 find 的手册页,尤其是说明链接测试的逻辑运算符的评估顺序的部分。手册页说:
OPERATORS
Listed in order of decreasing precedence:
( expr )
Force precedence. Since parentheses are special to the shell,
you will normally need to quote them.
Many of the examples in this manual page use backslashes
for this purpose: `\(...\)' instead of `(...)'.
expr1 expr2
Two expressions in a row are taken to be joined with an
implied -a; expr2 is not evaluated if expr1 is false.
expr1 -a expr2
Same as expr1 expr2.
expr1 -o expr2
Or; expr2 is not evaluated if expr1 is true.
Please note that -a when specified implicitly (for example by two
tests appearing without an explicit operator between them) or
explicitly has higher precedence than -o. This means that
find . -name afile -o -name bfile -print will never print afile.
到目前为止一切顺利:我已经编译了两个程序:
#include <stdio.h>
int main (int argc, char **argv) {
printf("THIS IS PGM1. I RETURN FALSE.\n");
return 1;
}
和
#include <stdio.h>
int main (int argc, char **argv) {
printf("THIS IS PGM2. I RETURN TRUE.\n");
return 0;
}
然后我有:
lalev@dragonfly:~/example10$ ls -l
total 32
-rwxrwxr-x 1 lalev lalev 8296 Jan 18 12:16 pgm1
-rw-rw-r-- 1 lalev lalev 112 Jan 18 12:16 pgm1.c
-rwxrwxr-x 1 lalev lalev 8296 Jan 18 12:16 pgm2
-rw-rw-r-- 1 lalev lalev 111 Jan 18 12:16 pgm2.c
-rw-rw-r-- 1 lalev lalev 0 Jan 17 23:10 test1
lalev@dragonfly:~/example10$ find . -exec ./pgm1 \; -o -exec ./pgm2 \; -print
THIS IS PGM1. I RETURN FALSE.
THIS IS PGM2. I RETURN TRUE.
.
THIS IS PGM1. I RETURN FALSE.
THIS IS PGM2. I RETURN TRUE.
./pgm1.c
[...]
lalev@dragonfly:~/example10$
在我看来, find 评估逻辑运算符的方式与联机帮助页中的描述不同。它从左到右-o
具有-a
相同的优先级。我错过了什么吗?
答案1
您的测试没有表现出优先级差异;尝试
find . -exec ./pgm1 \; -print -o -exec ./pgm2 \;
看看差异。-a
(或没有运算符)的绑定比 更强-o
,因此-print
绑定到-exec ./pgm1
并且永远不会被评估,因为pgm1
总是失败。
在您的示例中,对于它找到的每个文件,find
运行pgm1
,它失败,导致find
评估运算符的另一个分支-o
,因此运行pgm2
,它成功,然后是-print
。
答案2
find . -exec ./pgm1 \; -o -exec ./pgm2 \; -print
|---expr1-----| |----expr2------------|
的退出代码pgm1
始终是1,这意味着 expr1 为假。根据手册页将评估 expr2,在本例中find
就是这样。pgm2
于是两人pgm1
都pgm2
被处决了。
答案3
再次总结一下,看看这次是否我明白了:find 总是以这样的方式评估谓词,它将命令行分成两部分——“左”和“右”部分。当它决定如何分割它时,运算符优先级将占据控制权,并且该行将在优先级最低的运算符处分割。然后首先执行左侧部分,最后执行右侧部分。如果每个部分有两个以上的谓词,并由逻辑运算符连接,则它会以相同的方式递归执行。
答案4
所以,基本上 -and 的更高优先级并不意味着它首先执行,而是意味着它最后执行......这就是“-a 比 -o 绑定更多”。