
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 -o
e -a
tem 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 -print
está vinculado -exec ./pgm1
e nunca é avaliado, pois pgm1
sempre falha.
No seu exemplo, para cada arquivo encontrado, ele find
executa pgm1
, que falha, fazendo com que find
a outra ramificação do -o
operador 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, find
avaliaremos expr2, que é pgm2
neste caso.
Então, ambos pgm1
e pgm2
foram 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".