findの動作に関する質問

findの動作に関する質問

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.

これまでのところ順調です。2 つのプログラムをコンパイルしました。

#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、 and-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 が false であることを意味します。man ページによると、この場合はfindexpr2 が評価されます。pgm2

それで、pgm1との両方がpgm2処刑されました。

答え3

もう一度要約して、今回理解できたかどうかを確認します。find は常に述語を評価し、コマンド ラインを「左」と「右」の 2 つの部分に分割します。分割方法を決定する際、演算子の優先順位が制御され、行は優先順位が最も低い演算子で分割されます。次に、左の部分が最初に実行され、最後に右の部分が実行されます。各部分に 2 つ以上の述語があり、論理演算子で結合されている場合は、同じ方法で再帰的に実行されます。

答え4

したがって、基本的に -and の優先順位が高いということは、最初に実行されるという意味ではなく、最後に実行されるという意味です...つまり、「-a は -o よりもバインドされます」。

関連情報