テスト目的で、次のディレクトリを作成しました。
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
発生します。デフォルトでは、サブディレクトリに進む前に、現在アクセスしているディレクトリ内のすべての一致する項目にアクションが適用されます。
-depth
の呼び出しに追加すると、検索パスの深さ優先検索find
が実行find
されます。つまり、rmdir
ディレクトリに対して を実行すると、既にそのディレクトリにアクセス済みであり、再度アクセスしようとしないことになります。
このため、-depth
を使用する場合は オプションが暗黙的に指定されます(を持つの実装の場合)。-delete
find
-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 {} +
これは完璧ではありません。ネストされたディレクトリや一致するディレクトリの数が多いと、エラー メッセージが印刷される可能性がありますが、質問の単純なケースではこれで機能するはずです。