`find -type d -exec rmdir {}\;` コマンドが「ファイルやディレクトリメッセージがありません」を生成するのはなぜですか

`find -type d -exec rmdir {}\;` コマンドが「ファイルやディレクトリメッセージがありません」を生成するのはなぜですか

テスト目的で次のディレクトリを作成しました。

user@linux:~$ mkdir dir0{1..3}

user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei  31 10:45 dir01
drwxr-xr-x 2 user user 4.0K Mei  31 10:45 dir02
drwxr-xr-x 2 user user 4.0K Mei  31 10:45 dir03
user@linux:~$ 

それから削除しました。find -exec

user@linux:~$ find -type d -exec rmdir {} \;
rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory
find: ‘./dir01’: No such file or directory
find: ‘./dir03’: No such file or directory
user@linux:~$ 

ディレクトリが削除されたことを確認しました。

user@linux:~$ ls -l
total 0
user@linux:~$ 

私の質問は次のとおりです

1)なぜこのようなメッセージがあるのか​​わかりません。理由をご存知ですか?

rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory

このエラーは表示されません。rmdir

user@linux:~$ mkdir dir0{1..3}
user@linux:~$ 

user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei  31 22:58 dir01
drwxr-xr-x 2 user user 4.0K Mei  31 22:58 dir02
drwxr-xr-x 2 user user 4.0K Mei  31 22:58 dir03
user@linux:~$ 

user@linux:~$ rmdir *
user@linux:~$ 

user@linux:~$ ls -l
total 0
user@linux:~$ 

2) このメッセージを削除できますか?

答え1

削除したばかりのディレクトリに入ろうとするので、find「該当ファイルやディレクトリがありません」エラーが発生します。find既定では、サブディレクトリに進む前に、現在アクセスしているディレクトリから一致するすべてのコンテンツにそのアクションを適用します。

make呼び出しに追加すると、-depth検索パスに対して深度優先検索が実行されます。これは、ディレクトリから実行すると、すでにそのディレクトリにアクセスして再アクセスしようとしないことを意味します。findfindrmdir

このため(has実装では)この-depthオプションは暗黙的です。-deletefind-delete

find . -depth -type d -exec rmdir {} \;

-depthこれはユーティリティの標準オプションですfind

rmdirこれは空のディレクトリでのみ機能することに注意してください。空でないディレクトリが多い場合、上記のコマンドを実行すると多くのエラーメッセージが生成されます。

代わりにfindサポートしている場合は、以下を使用してください-empty

find . -type d -empty -delete

これにより、空のディレクトリが削除されます。

次のいずれかにfind非標準はありません。-delete-emtpy

find . -depth -type d -exec sh -c '
    for dirpath do
        set -- "$dirpath"/*
        [ ! -e "$1" ] && rmdir "$dirpath"
    done' sh {} +

見つかったディレクトリが空であることをテストし、空の場合は削除します。

これは、空でないディレクトリが原因でいくつかのエラーメッセージが表示されるのを防ぐための長いコードです。はい生成されたコンテンツが「許可拒否」エラーである可能性があるため、より興味深いものになることを願っています。エラーを/dev/null一番上の最初のコマンドにリダイレクトすると、これらのエラーは非表示になります。find

答え2

おそらく何が起こっているのかは、-exec ... \;生成によって find 操作が段階的に実行されることです。

  • ディレクトリツリーを参照して一致するものを見つけます-type d
  • rmdirそのエントリが見つかったらすぐに実行します。

これは、あなたの例では、findがdir01後で入力用のディレクトリとして覚えてrmdir実行してから再帰しようとしたときにもはやdir01存在しないので失敗することを意味します。

この場合、次のように実行すると役立ちます。-exec rmdir {} +単一の呼び出しが発行されます。rmdir dir01 dir02 dir03これにより、最後の3つのエラーメッセージが削除されます。

エラーメッセージは、現在のディレクトリが実際にはディレクトリですが空ではないため、削除できるディレクトリではないため.です。それについて考えたくない場合は、次のコマンドを実行してください。.rmdir-min-depth

find -mindepth 1 -type d -exec rmdir {} +

これは完璧ではありません。入れ子になったディレクトリや一致するディレクトリが多い場合でも、エラーメッセージが表示されることがありますが、これは問題の簡単な場合には機能します。

関連情報