Pregunta sobre el comportamiento de encontrar

Pregunta sobre el comportamiento de encontrar

Tengo problemas para descifrar la página del manual de find y sobre todo la parte que indica el orden de evaluación de los operadores lógicos que vinculan las pruebas. La página de manual dice:

 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.

Hasta ahora todo bien: he compilado dos programas:

#include <stdio.h>

int main (int argc, char **argv) {
        printf("THIS IS PGM1. I RETURN FALSE.\n");
        return 1;
}

y

#include <stdio.h>

int main (int argc, char **argv) {
        printf("THIS IS PGM2. I RETURN TRUE.\n");
        return 0;
}

Luego tengo:

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$

Me parece que la forma en que find evalúa los operadores lógicos difiere de la descripción en la página de manual. Va de izquierda a derecha -oy -atiene la misma prioridad. ¿Me estoy perdiendo de algo?

Respuesta1

Su prueba no demuestra diferencias de precedencia; intentar

find . -exec ./pgm1 \; -print -o -exec ./pgm2 \;

para ver la diferencia. -a(o ningún operador) se vincula con más fuerza que -o, por lo que -printestá vinculado -exec ./pgm1y nunca se evalúa ya que pgm1siempre falla.

En su ejemplo, para cada archivo que encuentra, findejecuta pgm1, lo cual falla, lo que hace findque se evalúe la otra rama del -ooperador, por lo que ejecuta pgm2, que tiene éxito, seguido de -print.

Respuesta2

find . -exec ./pgm1 \; -o -exec ./pgm2 \; -print
       |---expr1-----|    |----expr2------------|

El código de salida de pgm1es siempre1, lo que significa que expr1 es falso. Según la página del manual findse evaluará expr2, que es pgm2en este caso.

Así que ambos pgm1fueron pgm2ejecutados.

Respuesta3

Para resumir una vez más para ver si lo entendí esta vez: find siempre evalúa los predicados de tal manera que divide la línea de comando en dos: la parte "izquierda" y la "derecha". Cuando decide cómo dividirla, el operador con prioridad toma el control y la línea se divide por el operador con menor prioridad. Luego se ejecuta primero la parte izquierda y finalmente, la parte derecha. Y si cada parte tiene más de dos predicados, unidos por un operador lógico, se ejecuta recursivamente de la misma manera.

Respuesta4

Entonces, básicamente la precedencia más alta de -and no significa que se ejecuta primero, sino que se ejecuta al final... Es decir, "-a vincula más que -o".

información relacionada