Write script to backup files and delete old backups:



mkdir -p $BACKUPDIR

CURRENT="$BACKUPDIR/`date +%Y-%m-%d`-files.tar.gz"

cd /var/ && tar czf $CURRENT www

find $BACKUPDIR -type f -mtime $ROTATE -exec rm {} \;

chmod 0600 $BACKUPDIR/*

Command Line (for testing):

find $BACKUPDIR -type f -mtime $ROTATE -exec rm {} \;

Somehow, the script does not work. However, if I execute it in the console, all is OK and old files get deleted. But if I run the script, files are not deleted (tar archive get created when I run the script). Why?

Script permissions are 755.

  • 1
    If you want to delete files more than 24hrs old, you should specify -mtime +0 for find. -mtime 1 means files 24hrs to 48hrs old.
    – yaegashi
    Jul 27 '15 at 6:30
  • 3
    -mtime 1 mean exactly 1 day old from now, so may be there are not such files in your $BACKUPDIR
    – Costas
    Jul 27 '15 at 7:51
  • 2
    rather than -exec rm {}, you might want to use the -delete option.
    – FelixJN
    Jul 27 '15 at 8:39

As suggested by Fiximan, you probably want to use the -delete option, although that should make no difference in your situation, if you were to hit a filename with spaces or other special characters, your script would fail.

#!/bin/sh -e


# I suggest a little more than 1 day (i.e. about 1 week of backups is
# probably safer.)

mkdir -p $BACKUPDIR

CURRENT="$BACKUPDIR/`date +%Y-%m-%d`-files.tar.gz"

# Create protected file, then backup data in it
touch $CURRENT
chmod 600 $CURRENT
cd /var/ && tar czf $CURRENT www

# Here we have the attempt at deleting, notice the "+"
find $BACKUPDIR -type f -name '*-files.tar.gz' -mtime +$ROTATE -delete

A few things:

  1. ROTATE=1 does not seem to make much sense, you probably want more than 1 backup, just in case. You often notice something's wrong a few days in... good luck if you have a backup from last night only!

  2. chmod 600 $CURRENT should be done as soon as possible; if you are really afraid for the security of the file, do it before creating the tarball (as shown in my sample.)

  3. Fix the find by adding a + in front of the $ROTATE number. This is something that gets me each time, so don't feel bad. Actually, if you use + it has the mean of older or equal, and if you use '-', the test is inverted (so -mtime +7 is more or less equivalent to ! -mtime -7 — probably within 1 day in between which is not unlikely to match one side or the other.) With a plain number as you used (-mtime 1), it will delete files that were modified on that particular day. If that script does not run for 3 days, then those 3 files won't ever get deleted.

  4. It is easier to use the -delete so you do not have to think about the quotations you missed in your sample code (i.e. -exec rm "{}" \;) in case the filename includes special characters.

  5. I suggest you add a -name because you have a simple way to know whether the file in question is a backup. This is just for security. If you never ever put any other file in that directory (like a copy of a backup you want to keep for a longer period of time) then you do not need it.

  6. Adding the -e option in the hash bang (#!/bin/sh -e) is a good idea so the script stops on the very first error. At times scripts run, generate errors, and you never see them.

  • FYI, -exec rm {} \; is perfectly safe as far as whitespace and special characters go. It won't delete directories, but that's not called for in this case.
    – Wildcard
    Jul 30 '19 at 22:57

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.