「find -delete」がディレクトリ内のすべてのファイルを再帰的に削除する理由


15

したがって、unixの次の動作は、私に多大なコストをかけています。

> touch foo
> touch bar
> ls  
bar  foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar  baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?

これはどういう意味ですか?


2
この質問は関連しており、将来の読者にとって興味深いかもしれません。unix.stackexchange.com/questions/101282/…–
ベルンハルト

回答:


14

findのコマンドラインは、さまざまな種類のオプションから作成され、それらが組み合わされて式を形成します。

findオプションは-deleteアクションです。
つまり、これまでに一致した各ファイルに対して実行されます。
パスの後の最初のオプションとして、すべてのファイルが一致します...おっと!

危険ですが、少なくともmanページには大きな警告があります

からman find

ACTIONS
    -delete
           Delete  files; true if removal succeeded.  If the removal failed, an
           error message is issued.  If -delete fails, find's exit status  will
           be nonzero (when it eventually exits).  Use of -delete automatically
           turns on the -depth option.

           Warnings: Don't forget that the find command line is evaluated as an
           expression,  so  putting  -delete first will make find try to delete
           everything below the starting points you specified.  When testing  a
           find  command  line  that  you later intend to use with -delete, you
           should explicitly specify -depth in order to avoid later  surprises.
           Because  -delete  implies -depth, you cannot usefully use -prune and
           -delete together.


さらに上からman find

EXPRESSIONS
    The expression is made up of options (which affect overall operation rather
    than  the  processing  of  a  specific file, and always return true), tests
    (which return a true or false value), and actions (which have side  effects
    and  return  a  true  or false value), all separated by operators.  -and is
    assumed where the operator is omitted.

    If the expression contains no actions other than  -prune,  -print  is  per‐
    formed on all files for which the expression is true.


findコマンドが何をするか試してみると:

コマンドがどのようなものかを確認するには

find . -name '*ar' -delete

あなたが最初のアクションを置き換えることができ、削除させていただきます-deleteより無害な作用によって-のように-fls-print

find . -name '*ar' -print

これにより、アクションの影響を受けるファイルが出力されます。
この例では、-printは省略できます。この場合、アクションはまったくないため、最も明白なものは暗黙的に追加されます-print。(上記の「表現」セクションの2番目の段落を参照)


私は、マニュアル最初のを読んでいないためだけの馬鹿だったと思います..しかし、それだけで追加することがとても簡単なように見えた-deleteフラグを:-)しかし、誰もがこれまでどうなる何らかの理由があるfind . -deleteのではなくはrm -rf .?それとも、たまたまfind引数を解析して処理する方法なのでしょうか?
mszep 14

1
構文は非常に危険であることに完全に同意します-しかし、それはfindのコマンドライン構文の特殊なケースであり、非常に強力であるため、回避するのは困難です。「強力なチェーンソーのように強力
フォルカージーゲル14

引用されたマニュアルページにはwarning: use -depth when testing stuff you later want to -delete、実際のサイドの例であなたがしなかったことが書かれていませんか?
pqnet 14

ああ、そうです-問題は見出しです- -nオプションのように-deleteの代わりにprintを使用することを説明するつもりでした。もちろん、最初のコマンドは実際に使用されるべきではありません。変更します。
フォルカーシーゲル14

9

find引数の順序は、多くの問題になります。

引数には、オプション、テスト、およびアクションを指定できます。通常は、最初にオプションを使用し、次にテストを実行し、次にアクションを使用する必要があります。

場合によってはfind、不適切な順序付けについて警告することもあります(-maxdepth他の引数の後に使用する場合など)が、そうでない場合もあります。

find . -delete -name '*ar'が:

  1. 現在のディレクトリでファイルとディレクトリを検索します。
  2. それらが見つかったときにそれらをすべて削除します!
  3. 次に、「* ar」のように名前が付けられているかどうかを確認します(この部分は今は効果がありません)。

おそらくやりたいことは:

find -name '*ar' -delete

これは、すべてのファイルについて、一致する'*ar'かどうかを確認し、条件を満たす場合にのみファイルを削除します。

遅すぎてごめんなさい。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.