All we need is an easy explanation of the problem, so here it is.
The command
$ find ~ -name .DS_Store -ls -delete
works on Mac OS X, but
$ find ~ -name __pycache__ -type d -ls -delete
does not – the directories are found but not deleted.
Why?
PS. I know I can do
$ find ~ -name __pycache__ -type d -ls -exec rm -rv {} +
the question is why find -delete
does not work.
How to solve :
I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.
Method 1
find
‘s -delete
flag works similar to rmdir
when deleting directories. If the directory isn’t empty when it’s reached it can’t be deleted.
You need to empty the directory first. Since you are specifying -type d
, find
won’t do that for you.
You can solve this by doing two passes: first delete everything within dirs named __pycache__
, then delete all dirs named __pycache__
:
find ~ -path '*/__pycache__/*' -delete
find ~ -type d -name '__pycache__' -empty -delete
Somewhat less tightly controlled, but in a single line:
find ~ -path '*/__pycache__*' -delete
This will delete anything within your home that has __pycache__
as part of its path.
Method 2
There are a couple potential reasons for this.
1)
You told it to delete directories only (-type d
), and those directories still have files inside them.
2)
Your directories only contain other directories, so the -type d
will take care of the contents issue. However you are using OS-X, which is largely based on FreeBSD, and the FreeBSD find
by default will process the directory before its contents.
However the -depth
option exists to solve this problem by telling find
to process the directory after its contents.
find ~ -name __pycache__ -type d -ls -delete -depth
This issue does not exist on linux because the -delete
option implicitly enables -depth
.
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.
Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0