Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.
mkdir foodir
find . -iname foodir -exec rm -fr {} \;

It does the job, but barfs message:

find: `./foodir': No such file or directory
share|improve this question
    
You can use the (non standard) -delete option of find to avoid that, instead of -exec rm. As for the reason, Michael Kjörling gave you the answer. –  Totor Mar 22 '13 at 13:20

4 Answers 4

up vote 5 down vote accepted

The exact sequence of events would go something like

  1. create foodir
  2. launch find
    1. find reads the current directory, caches the result and then iterates over it, finding an entry for foodir
    2. find launches the exec command for foodir, deleting foodir
    3. find tries to recurse into foodir (it's in find's internal cache), which no longer exists
    4. find displays a warning that it was unable to recurse into foodir
    5. find continues with the next entry (which in this case likely is the end of the list of directory entries, so it exits having done its job to the best of its ability)

So what you are seeing is perfectly explainable, if somewhat unexpected from an outside perspective.

The caching is almost certainly done to improve performance, saving a potentially large number of system calls as well as quite a bit of potential disk I/O for every file. Without a transactional file system, which is common but not guaranteed, there's no guarantee you wouldn't hit issues like this even if find did read the directory once for each entry; and in the case of non-local file systems in particular, even the order of the entries might change between checks, so you can't simply keep track of an index either but must keep track of every directory entry you have visited. For a large directory hierarchy, that becomes prohibitive very quickly.

In general, this is termed a "race condition": a precondition for a calculation changing between when the calculation is done and when the resulting value is used.

Looking at the man page for GNU find, there is an option -ignore_readdir_race which might help to suppress the warning. However, I don't know how much this does for any other commands executed through find. Depending on your needs, that may be sufficient. You can also suppress any errors and warnings from find by redirecting its standard error to /dev/null (append 2>/dev/null to the command line), but I do not recommend that since it can hide more serious errors. I also don't know off hand how that would interact with any error output from the invoked command.

share|improve this answer
    
is there any way to get rid of these messages? –  Marcus Junius Brutus Mar 22 '13 at 10:26
    
It looks like -ignore_readdir_race will do that. –  Michael Kjörling Mar 22 '13 at 10:34
    
You can use the -depth option to recurse through a directory before handling the directory itself. –  Simon Richter Mar 22 '13 at 13:01

find stats the target directory as it starts up to get the directory's contents. It then processes the commands you gave it, which, in this instance, change the directory's contents by removing an entry. Therefore, find's idea of what the directory contains, and reality are at odds, and it issues the warning message.

share|improve this answer

That seems to make sense - your command finds foodir then removes it. Ordering of commands is the reason for the message.

share|improve this answer
    
The command finds foodir, then removes it. Agreed. At which point therefore is foodir not found? ("No such file or directory"). –  Marcus Junius Brutus Mar 22 '13 at 9:50

Use this command instead

find . -iname foodir | xargs rm -Rf
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.