Вопрос о поведении находки

Вопрос о поведении находки

У меня возникли проблемы с расшифровкой страницы руководства find, особенно той части, где указан порядок оценки логических операторов, связывающих тесты. На странице руководства говорится:

 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.

Пока все хорошо: я составил две программы:

#include <stdio.h>

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

и

#include <stdio.h>

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

Тогда у меня есть:

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$

Мне кажется, что способ, которым find оценивает логические операторы, отличается от описания на странице руководства. Он идет слева направо, -oи и -aимеют одинаковый приоритет. Я что-то упускаю?

решение1

Ваш тест не демонстрирует различий в приоритетах; попробуйте

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

чтобы увидеть разницу. -a(или отсутствие оператора) связывает сильнее, чем -o, поэтому -printсвязан с -exec ./pgm1и никогда не оценивается, поскольку pgm1всегда терпит неудачу.

В вашем примере для каждого найденного файла findзапускается pgm1, что завершается неудачей, заставляя findоценить другую ветвь оператора -o, поэтому запускается pgm2, что завершается успешно, а затем -print.

решение2

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

Код выхода pgm1всегда1, что означает, что expr1 ложно. Согласно странице руководства findбудет оценивать expr2, что pgm2в данном случае.

Так что оба pgm1были pgm2казнены.

решение3

Подведем итоги еще раз, чтобы увидеть, правильно ли я понял на этот раз: find всегда оценивает предикаты таким образом, что разделяет командную строку на две части — «левую» и «правую». Когда он решает, как ее разделить, приоритет операторов берет на себя управление, и строка разделяется по оператору с наименьшим приоритетом. Затем сначала выполняется левая часть, а затем, в конечном итоге, правая часть. И если каждая часть имеет более двух предикатов, объединенных логическим оператором, она выполняется рекурсивно тем же способом.

решение4

Таким образом, по сути, более высокий приоритет -and не означает, что он будет выполнен первым, а означает, что он будет выполнен последним... То есть «-a связывает больше, чем -o».

Связанный контент