Strange behavior of find and rm command

Hi

I run the below command to find and delete *.xml files 90 or more days old.

find . -type f -name '*.xml' -mtime +90 -exec rm {} \;
find: stat() error ./Hello/2014_EMPTY.xml: No such file or directory
./Hello/2014_EMPTY_8011.xml: No such file or directory
.....
....

If the file does not exists why is the my find even finding it and trying to delete something that does not exist?

Is it caching the find results causing this problem ?

I was not seeing this behaviour. Any guesses on how can i get my command working ?

I am on Unix Sparc.

First off, add echo before rm. Never ever ever run a batch deletion script you haven't tested.

This is suppose to run as a crontab.

I had use this command with rm -i option and it all looked good in the first run.

Could be my crontab tab is running in the background and its is deleting the files and when i run it manually it does not find the file .. .thats my wild guess. But how can i confirm ?

ps -ef | grep purge.sh

does not yield any results where purge.sh has that find and remove command i post in the OP; to show that the BG process is running or maybe there is a problem with the ps command :slight_smile:

Not sure what has happened now ?

An error message like that usually means that another process removed that file while find was walking the file hierarchy. In other words:

  1. find used readdir() or getdents() to read a name from the directory it is processing,
  2. another process unlinks or renames the filename just read by find , and then,
  3. find tries to stat() the file to check the file's timestamps and gets the error you listed.
2 Likes

Say if another process as part of the crontab is running in the background that is deleting the file ... how can i find it's pid ?

The disk space usuage is reducing indicating that there must be a process running in the bg as part of the crontab.

Both the below commands do not yield any results.

bash-3.2$ /usr/ucb/ps -auxwww | grep purge*
bash-3.2$ /usr/ucb/ps -auxwww | grep find*

How can i stop the process ?

Nothing says that the other process that removed, moved, or deleted that file was being run by another find command nor that it had been started by cron . Anybody logged on to your network with write access to the directory in question could remove a file. And, by the time you see the error message, that process could already be gone. There might not be a running process left to find. If you have process accounting running, you might be able to find who was running another process at the time find reported the error.

Of course if you were running the two copies of the same script at the same time, you could easily see several errors like that as they fight with each other trying to be the first one to find and process the selected files. But, if you have only seen this once, it is more likely that someone manually removed a file while your cron job was running.

I hate find I've found it be to FAIL so many more times than successful.

You'd see better speed (and shorter arguments) ls -1 'ing to a temp file, grep 'ing the tmp, then cleaning up.

Find is THAT slow and shi**y.

1 Like

Ampsys,

Perhaps find is being more thorough than you. It is a very good tool, and better than using ls -1 and then mangling the output yourself.

Consider that find will descend directories and look at your directory structure to see how that might affect you. If you have many sub-directories and then more within that along with many many files, then find will be trawling them all because that is what you will have asked it to do.

If you don't want to use all the strengths of find, you can turn them off if you wish. If you have a poor directory design, then that is not the fault of find

This isn't really the place to complain about tools that run slowly because of your poor design.

Robin

1 Like

If ls -1 is convenient for you then you should compare with a flat run

find . \! -name . -prune -print
1 Like

ls will wait hours then coredump on a large enough directory -- because it sorts, all the time, and that can't be turned off. find will never pull that trick on you. and returns results immediately.

If you know how to use it, find is extremely reliable. Its options are admittedly tricky.

You can turn off sorting in ls when you use the -f option, but that has side effects ( -f turns on -a , and the results are unspecified in you use -f with -l and a few other options).

1 Like