2

I'm using find in a bash script to clean up some cached files more than a day old:

find /tmp/my_files_*.cache -mtime +1 -delete

The problem is if the command matches no files it fails which prevents the rest of the script from running:

find: `/tmp/my_files_*.cache': No such file or directory

I'm currently working around it by appending || true to the command but this is suboptimal as the error still appears in the output and it allows the script to continue past any other error that find might throw.

How can I tell find that it's OK if no files match?

Tamlyn
  • 123
  • 3
  • 1
    How are you detecting the error ? – user9517 Aug 26 '16 at 10:41
  • 4
    Take a look at the answer here http://serverfault.com/questions/540460/find-how-to-not-have-errors-stderr-when-no-files-exists basically you do a file count and if it isn't 0 you run the find and delete, if it is 0 you move on – Drifter104 Aug 26 '16 at 10:47

3 Answers3

2
find /tmp -name "*.cache" -mtime +1 -delete
Ipor Sircer
  • 1,226
  • 7
  • 8
  • Ah nice, because `/tmp` always exists it doesn't complain if the `name` filter reduces the matched set to zero. – Tamlyn Aug 26 '16 at 16:15
  • 1
    I think it's worth noting that while this is proper use of `find` it's not an equivalent command to what the question was about. `find /tmp -maxdepth 1 -name "my_files_*.cache" -mtime +1 -delete` would actually do what the command in the question attempted to do. – Håkan Lindqvist Aug 26 '16 at 21:17
1

With your original command, it's not actually find that fails to match anything but your shell.

Ie, when you run

find /tmp/my_files_*.cache -mtime +1 -delete

If there were matching files, the shell's globbing functionality expanded that wildcard and the actual find invocation would look something like:

find /tmp/my_files_1.cache /tmp/my_files_2.cache /tmp/my_files_3.cache -mtime +1 -delete

(this could easily become a very long command, which in some cases can be a problem in itself)

When there are no matches, the wildcard is passed as-is, so the find invocation would look like:

find /tmp/my_files_*.cache -mtime +1 -delete

and behaving like most programs find does not do any sort of wildcard expansion on its own for the path argument(s), so it tries to find a file/directory that is literally named /tmp/my_files_*.cache, hence the error.

As was pointed out by Ipor Sircer, the more idiomatic way of using find is to instead give it the base path(s) and let find itself look through the directory contents and apply filters as needed.

Something like this should match what you were trying to do:

find /tmp -maxdepth 1 -name "my_files_*.cache" -mtime +1 -delete
Håkan Lindqvist
  • 35,011
  • 5
  • 69
  • 94
-1

If you do not care whether there are any files to delete or not then don't bother to test for the success or not, just throw away any error:

find /tmp/my_files_*.cache -mtime +1 -delete 2> /dev/null

Unbeliever
  • 2,336
  • 1
  • 10
  • 19