关于 find 行为的问题

关于 find 行为的问题

我无法破译 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

于是两人pgm1pgm2被处决了。

答案3

再次总结一下,看看这次是否我明白了:find 总是以这样的方式评估谓词,它将命令行分成两部分——“左”和“右”部分。当它决定如何分割它时,运算符优先级将占据控制权,并且该行将在优先级最低的运算符处分割。然后首先执行左侧部分,最后执行右侧部分。如果每个部分有两个以上的谓词,并由逻辑运算符连接,则它会以相同的方式递归执行。

答案4

所以,基本上 -and 的更高优先级并不意味着它首先执行,而是意味着它最后执行......这就是“-a 比 -o 绑定更多”。

相关内容