web-dev-qa-db-ja.com

find -deleteは空でないディレクトリを削除しません

コマンド

$ find ~ -name .DS_Store -ls -delete

mac OS Xで動作しますが、

$ find ~ -name __pycache__ -type d -ls -delete

しない-ディレクトリは見つかりますが、削除されません。

なぜ?

PS。できることはわかっている

$ find ~ -name __pycache__ -type d -ls -exec rm -rv {} +

質問はなぜfind -deletenotを実行します。

35
sds

find-deleteフラグは、ディレクトリを削除するときに rmdir と同様に機能します。到達したときにディレクトリが空でない場合は、削除できません。

最初にディレクトリを空にする必要があります。 -type dを指定しているので、findはそれを行いません。

これを解決するには、2つのパスを実行します。最初に__pycache__という名前のディレクトリ内のすべてを削除してから、__pycache__という名前のすべてのディレクトリを削除します。

find ~ -path '*/__pycache__/*' -delete
find ~ -type d -name '__pycache__' -empty -delete

やや厳しく制御されていませんが、1行で:

find ~ -path '*/__pycache__*' -delete

これにより、__pycache__がパスの一部として含まれている家の中のすべてが削除されます。

39
GnP

これにはいくつかの理由が考えられます。

1)ディレクトリ(-type d)のみを削除するように指示しましたが、それらのディレクトリ内にはファイルが残っています。

2)ディレクトリには他のディレクトリしか含まれていないため、-type dがコンテンツの問題を処理します。ただし、OS-Xを使用しています。これは、主にFreeBSDに基づいており、FreeBSD findはデフォルトで、その内容の前にディレクトリを処理します。
ただし、findにその内容の後にディレクトリを処理するように指示することにより、この問題を解決するために-depthオプションが存在します。

find ~ -name __pycache__ -type d -ls -delete -depth

-deleteオプションは暗黙的に-depthを有効にするため、この問題はLinuxでは発生しません。

FreeBSD man 1 find

 -depth  Always true; same as the non-portable -d option. Cause find to
   perform a depth-first traversal, i.e., directories are visited in
   post-order and all entries in a directory will be acted on before
   the directory itself. By default, find visits directories in
   pre-order, i.e., before their contents. Note, the default is not
   a breadth-first traversal.

GNU man 1 find

 -depth Process each directory's contents before the directory itself. The -delete
        action also implies -depth.
6
Patrick