Pergunta sobre o comportamento de find

Pergunta sobre o comportamento de find

Tenho dificuldade em decifrar a página de manual do find e principalmente a parte que indica a ordem de avaliação dos operadores lógicos que vinculam os testes. A página de manual diz:

 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.

Até aí tudo bem: compilei dois programas:

#include <stdio.h>

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

e

#include <stdio.h>

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

Então eu tenho:

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$

Parece-me que a forma como find avalia os operadores lógicos difere da descrição na página de manual. Vai da esquerda para a direita -oe -atem igual prioridade. Estou esquecendo de algo?

Responder1

Seu teste não demonstra diferenças de precedência; tentar

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

para ver a diferença. -a(ou nenhum operador) vincula-se com mais força que -o, portanto -printestá vinculado -exec ./pgm1e nunca é avaliado, pois pgm1sempre falha.

No seu exemplo, para cada arquivo encontrado, ele findexecuta pgm1, que falha, fazendo com que finda outra ramificação do -ooperador seja avaliada, portanto, execute pgm2, que é bem-sucedido, seguido por -print.

Responder2

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

O código de saída de pgm1é sempre1, o que significa que expr1 é falso. De acordo com a página de manual, findavaliaremos expr2, que é pgm2neste caso.

Então, ambos pgm1e pgm2foram executados.

Responder3

Para resumir mais uma vez para ver se consegui desta vez: find sempre avalia os predicados de tal maneira que divide a linha de comando em duas - parte "esquerda" e "direita". Quando decide como dividi-la, a precedência do operador assume o controle e a linha é dividida no operador com menor precedência. Em seguida, a parte esquerda é executada primeiro e, eventualmente, a parte direita. E se cada parte tiver mais de dois predicados, unidos por um operador lógico, ela será executada recursivamente da mesma maneira.

Responder4

Então, basicamente, a precedência mais alta de -and não significa que ele será executado primeiro, mas significa que será executado por último... Isso é "-a liga mais que -o".

informação relacionada