
我無法破解 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 綁定更多」。