關於 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 綁定更多」。

相關內容