21

I need to remove files older than 3 days with a cron job in 3 different directories. (these 3 directories are children of a parent directory /a/b/c/1 & /a/b/c/2 & /a/b/c/3) Can this be done with one line in the crontab?

26

This is easy enough (although note that this goes by a modification time more than 3 days ago since a creation time is only available on certain filesystems with special tools):

find /a/b/c/1 /a/b/c/2 -type f -mtime +3 #-delete

Remove the # before the -delete once you are sure that it is finding the files you want to remove.

To have it run by cron, I would probably just create an executable script (add a shebang - #!bin/sh to the top line of the file and make executable with chmod a+x), then put it in an appropriate cron directory like /etc/cron.daily or /etc/cron.weekly. Provided of course that you do not need a more specific schedule and that these directories exist on your distro.

Update

As noted below, the -delete option for find isn't very portable. A POSIX compatible approach would be:

find /a/b/c/1 /a/b/c/2 -type f -mtime +3 #-exec rm {} +

Again remove the # when you are sure you have the right files.

Update2

To quote from Stéphane Chazelas comment below:

Note that -exec rm {} + has race condition vulnerabilities which -delete (where available) doesn't have. So don't use it on directories that are writeable by others. Some finds also have a -execdir that mitigates against those vulnerabilities.

  • Thanks! Is there a way to specify the parent directory and then the child directories so the /a/b/c/ doesn't have to be specified for every option? – KingKongFrog Jun 12 '14 at 17:40
  • Sure, in a POSIX shell you can do /a/b/c/[12], but this is only really appropriate if the subdirectories have single letter names. In bash you can do /a/b/c/{1,2}. Of course then the bang line for a script would have to be #!/bin/bash or if you are using crontab, you need to make sure it is configured to use bash (I don't really recommend changing it if it isn't). – Graeme Jun 12 '14 at 17:52
  • 2
    brace expansion is a csh feature and is also supported by ksh, bash, zsh and fish so you have a wide choice of shells. ksh, bash and zsh also have alternation operators in their globs. Note that -exec rm {} + has race condition vulnerabilities which -delete (where available) doesn't have. So don't use it on directories that are writeable by others. Some finds also have a -execdir that mitigates against those vulnerabilities. – Stéphane Chazelas Jun 12 '14 at 18:59
  • Does rm -f not handle errors silently, thereby handling any possible race condition with -exec? – Acumenus Jul 8 '15 at 2:49
  • 1
9

You would be much better off using tmpwatch

tmpwatch recursively removes files which haven't been accessed for a given time. Normally, it's used to clean up directories which are used for temporary holding space such as /tmp.
  • 2
    tmpwatch has been forked to tmpreaper, which (at least on Debian) seems to be it's replacement. – Jaap Dec 1 '16 at 16:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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