Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a cache folder with minimum of 15000 files.

I tried this:

find cache* -mtime +30 -exec rm {} \;

But this made my server load fly to the skies!

Is there any faster/better solution?

Or can I limit speed or iterations of this command?

share|improve this question
If cache* expands to many files, you may want to try something like find . -name 'cache*' -mtime +30 -exec rm {} \; instead. – eldering Nov 6 '12 at 10:15
up vote 7 down vote accepted

I like to use tmpwatch for these things, this is for the last time the file was modifiyed. It's simple and works well in many cases:

tmpwatch -m 720 /path/to/cache

For Ubuntu, check tmpreaper instead.

If you want to check the last time the file was accessed than you use the following:

tmpwatch -a 720 /path/to/cache

You are not able to use tmpwatch -a on file systems mounted with noatime. you can still use -m

share|improve this answer
I'm using Ubuntu 10.04.2 LTS and that command doesn't exists.. – Kristian Nov 6 '12 at 10:47
@Kristian Check for tmpreaper instead. – slhck Nov 6 '12 at 11:07
@slhck Thanks ! – Kristian Nov 6 '12 at 11:12
Any pitfalls when using these to manage filesystems mounted with noatime option? – AnonymousLurker Nov 6 '12 at 11:28
@AnonymousLurker I have modifyed the answer for you – WojonsTech Nov 6 '12 at 19:42

You could avoid the spawning of a new process for each file by using

find cache* -mtime +30 -delete
share|improve this answer
What is the semi-colon for? – phihag Nov 6 '12 at 15:19
Ooops, copy-paste error. Although it does nothing (and is not harmful), I have removed it. – chiborg Nov 7 '12 at 8:22

Try running the above with nice:

nice -n 39 find cache* -mtime +30 -exec rm -f {} ';'

That way the huge load will only appear if nothing else needs to run, otherwise the other processes will take precedence (if their niceness is lower than 19 i.e. the maximum).

Note that the argument to the -n option is added to the default niceness which varies between -20 and 19. I used 39 so that it will be very nice regardless of what original niceness there was.

share|improve this answer

As commented by chiborg, the load is due to starting rm for every file found. I noticed the answer where tmpwatch is suggested as an alternative, which I'm sure works well. However, it is not necessary.

Find can run the command given to exec once, if you tell it to accumulate the found files into a list of arguments like so:

find /path -name "*.moo" -exec rm {} \+

This may sometimes fail to work because the argument list may grow larger (in bytes) than the maximum allowed by the shell (getconf ARG_MAX). This may be solved by xargs with the -L option.

consider this example:

$ echo 0 > /tmp/it; 
$ for i in {0..15000};do echo $i;done  |\
    xargs --no-run-if-empty -L 5000 ./tmp/ 
Iteration=0; running with 5000 arguments
Iteration=1; running with 5000 arguments
Iteration=2; running with 5000 arguments
Iteration=3; running with 1 arguments

$ cat tmp/ 
IT=`cat /tmp/it`
echo Iteration=$IT\; running with $# arguments
let IT=IT+1
echo $IT > /tmp/it

So there is no need install extra software, all you need is in gnu-findutils:

find /path -mtime +30 -print0 | xargs -0 -L 5000 rm 
share|improve this answer
Wow, mindblowing answer! Thanks :) – Kristian Nov 6 '12 at 16:00
some d00d thought it would be useful to add -print0 and -0 to find and xargs. Those arguments force their commands use the null char (\0) instead of a new-line (\n) to separate the arguments. This is helpful when the filename has spaces or new-lines in it. – Ярослав Рахматуллин Nov 7 '12 at 16:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .