linuxコマンドfind-exec操作の問題

2983 ワード

最近、あるディレクトリの下のフォルダを削除する必要があります.実は「CVS」というフォルダです.CVSを使ったことがある人はみな知っています.CVSはディレクトリの各レベルにCVSというフォルダを作ります.中にはCVSに関する情報が入っています.あるディレクトリの下にあるすべての「CVS」というフォルダを削除する必要があります.LINUXではfindコマンドを使用するのは簡単です.
find . -name CVS -exec rm -rf {} \;

問題ないように見えますが、間違えました.
find: `./CVS': No such file or directory

チェックしてみると、実は./CVSというフォルダは確かに存在し、この時点で削除されています.功徳は円満ですが、なぜ間違っていますか.
findがこの機能を完成させたことを覚えられないもう一つの書き方があります.
find . -name CVS -exec rm -rf {} \+

やってみると、意外なことに、このやり方が成功し、何の間違いも報告されていないのは疑問で、仕方なく男に助けを求めるしかない(man)
-exec command ;
          Execute  command;     true  if 0 status is returned.     All following
          arguments to find are taken to be arguments to the command until
          an  argument  consisting of ';' is encountered.  The string '{}'
          is replaced by the current file name being processed  everywhere
          it occurs in the arguments to the command, not just in arguments
          where it is alone, as in some versions of find.  Both  of     these
          constructions might need to be escaped (with a '\') or quoted to
          protect them from expansion by the shell.     See the EXAMPLES sec-
          tion  for examples of the use of the '-exec' option. 
The speci-           fied command is run once for each matched file.  The command  is
          executed    in  the     starting  directory.     There are unavoidable
          security problems surrounding  use  of  the  -exec  option;  you
          should use the -execdir option instead.
もう1つ:
-exec command {} +           This  variant  of the -exec option runs the specified command on           the selected files, but the command line is built     by  appending           each  selected file name at the end; the total number of invoca-           tions of the command will     be  much  less     than  the  number  of           matched  files.    The command line is built in much the same way           that xargs builds its command lines.  Only one instance of  '{}'           is  allowed  within the command.    The command is executed in the           starting directory.
長い間見ていたが、彼らの違いに気づいた.赤い字で表記されている.
つまり「-exec」+「;」一致するファイルごとに1回のコマンドが実行されます.ここではrm-rfコマンドですが、「-exec」+「+」は一致するファイル名をコマンドのパラメータappendとしてコマンドの後ろに置くだけです.つまり、rm-rf file 1 file 2 file 3
しかし、このような違いはなぜこのような明らかな違いを招いたのだろうか.考えて、悟った:
1の実行手順は次のとおりです.
1.対面レベルのすべてのディレクトリとファイルを記録し、一致するかどうかを比較します.
2.CVSというフォルダに一致し、コマンドrm-rf./CVS, 
3.前のレコードに基づいて複数のディレクトリを再帰的に巡回する場合、問題が発生し、プログラムが「CVS」という階層のディレクトリに入って巡回しようとした場合、このディレクトリは存在しないことが判明し、エラーが発生します.どうしてこのディレクトリがなくなったのか、ハッ、第2歩で削除されました!
検証可能:
find . -maxdepth 1 -name CVS -exec rm -rf {} \;

-maxdepthパラメータは、マッチングが現在のディレクトリでのみ発生し、サブディレクトリに深く入り込まないことを示し、結果としてこのコマンドはエラーを報告せず、以前の推測も検証した.
後で調べるために、ここに記録します.