Frage zum Verhalten von find

Frage zum Verhalten von find

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 -ound -ahat 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, -printist also an gebunden -exec ./pgm1und wird nie ausgewertet, da pgm1immer fehlschlägt.

In Ihrem Beispiel wird für jede gefundene Datei findausgeführt pgm1, was fehlschlägt, wodurch findder andere Zweig des -oOperators 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 pgm1ist immer1, was bedeutet, dass expr1 falsch ist. Laut Manpage findwird expr2 ausgewertet, was pgm2in diesem Fall zutrifft.

Also wurden beide pgm1hingerichtet 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“.

verwandte Informationen