Cron job to delete files older than 3 days

  • 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?

  • Graeme

    Graeme Correct answer

    6 years ago

    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?

    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).

    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.

    Does `rm -f` not handle errors silently, thereby handling any possible race condition with `-exec`?

    @StéphaneChazelas, could you please link to a more full explanation of the race condition you mentioned? I'm interested.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM