
Ich habe Probleme, die Manpage von find zu entziffern, insbesondere den Teil, der die Reihenfolge der Auswertung logischer Operatoren angibt, die die Tests verknüpfen. Die Manpage sagt:
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.
So weit, so gut: Ich habe zwei Programme zusammengestellt:
#include <stdio.h>
int main (int argc, char **argv) {
printf("THIS IS PGM1. I RETURN FALSE.\n");
return 1;
}
Und
#include <stdio.h>
int main (int argc, char **argv) {
printf("THIS IS PGM2. I RETURN TRUE.\n");
return 0;
}
Dann habe ich:
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$
Mir scheint, dass die Art und Weise, wie find logische Operatoren auswertet, von der Beschreibung in der Manpage abweicht. Es geht von links nach rechts -o
und -a
hat die gleiche Priorität. Übersehe ich etwas?
Antwort1
Ihr Test zeigt keine Unterschiede in der Priorität. Versuchen Sie
find . -exec ./pgm1 \; -print -o -exec ./pgm2 \;
um den Unterschied zu sehen. -a
(oder kein Operator) bindet stärker als -o
, -print
ist also an gebunden -exec ./pgm1
und wird nie ausgewertet, da pgm1
immer fehlschlägt.
In Ihrem Beispiel wird für jede gefundene Datei find
ausgeführt pgm1
, was fehlschlägt, wodurch find
der andere Zweig des -o
Operators ausgewertet wird. Daher wird ausgeführt pgm2
, was erfolgreich ist, gefolgt von -print
.
Antwort2
find . -exec ./pgm1 \; -o -exec ./pgm2 \; -print
|---expr1-----| |----expr2------------|
Der Exit-Code von pgm1
ist immer1, was bedeutet, dass expr1 falsch ist. Laut Manpage find
wird expr2 ausgewertet, was pgm2
in diesem Fall zutrifft.
Also wurden beide pgm1
hingerichtet pgm2
.
Antwort3
Um es noch einmal zusammenzufassen und zu sehen, ob ich es dieses Mal verstanden habe: find wertet Prädikate immer so aus, dass es die Befehlszeile in zwei Teile aufteilt – „linker“ und „rechter“ Teil. Wenn entschieden wird, wie die Teilung erfolgt, übernimmt die Operatorpriorität die Kontrolle und die Zeile wird beim Operator mit der geringsten Priorität geteilt. Dann wird zuerst der linke Teil ausgeführt und dann schließlich der rechte Teil. Und wenn jeder Teil mehr als zwei Prädikate hat, die durch logische Operatoren verbunden sind, wird er auf die gleiche Weise rekursiv ausgeführt.
Antwort4
Die höhere Priorität von -and bedeutet im Grunde nicht, dass es zuerst ausgeführt wird, sondern dass es zuletzt ausgeführt wird ... Das heißt, „-a bindet mehr als -o“.