find is working fine. i can reproduce the "error" but it is human error. think about it, what is find doing (as opposed to what you think find does). it took me a while to figure it out
.
setup:
Code:
$ ls
dir.1 dir.2 dir.3 dir.4
dir.1.tar.bz2 dir.2.tar.bz2 dir.3.tar.bz2 dir.4.tar.bz2
i wanted to rm all the dir (not the tar balls). i did:
Code:
$ find . -name 'dir.?' -exec rm -r '{}' \;
find: ./dir.1: No such file or directory
find: ./dir.3: No such file or directory
find: ./dir.4: No such file or directory
find: ./dir.2: No such file or directory
what does find do?
1. find takes (not necessarily) the first entry in the ./ directory. this would be e.g. dir.1/
2. it compares it to the pattern 'dir.?'. does it match? yes.
3. find executes "rm -r dir.1".
4. find tries to enter dir.1/ to find the pattern within the directory. it doesn't know anything about the exec command.
5. it doesn't find dir.1/ anymore. returns ENOENT (look at the strace output)
the same is true for the other dirs.
proof:
if you use:
Code:
$ find . -name 'dir.?' -exec rm -r '{}' +
instead, find first tries to find all occurences of the pattern and builds up the exec command occurence for occurence. after it travelled all the subdirs it will execute the command:
Code:
rm -r dir.1/ dir.2/ dir.3/ dir.4/
but be careful! if ./dir.1 containes another 'dir.?' you'll again get an error message saying:
Code:
rm: cannot remove `./dir.1/dir.1': No such file or directory
but this time it's rm complaining.
bottomline: don't use -exec. apart from such subtle trap lines it's unsecure. better use -execdir (see manpage). even better and easier, use xargs.
Code:
$ find . -name 'pattern' | xargs rm -r
cheers :::