I wrote a script a day ago that backs up my entire database and all of my /var/www files to a network share. It was my first try at scripting in Linux and all in all I think it is really cool. I would like to add a feature to my backup script. Currently, the script uses rsync to overwrite any existing data on the destination for the backup. I would like it actually create a unique, full backup, every time it runs. Right now I have it running every night at midnight. However, I only want to have 15 concurrent full backups at a time - so once it hits 15 backups I want it to start deleting the older backups. Can anyone point me in the right direction?

Here's my current script:

#!/usr/bin/env bash

# Mount the share
smbmount //address/folder /mnt/folder -o credentials=/root/.smbpasswd

# Synchronize the Web folder
rsync --delete -C -v -a -r /var/www /mnt/folder

# Create a backup of all databases
mysqldump -uuser -ppassword --all-databases | gzip -9 > /root/backup/Databases.sql.zip

# Copy the backup to the backup folder
cp /root/backup/Databases.sql.zip /mnt/folder/Databases.sql.zip

echo "Backup complete!"

Don't reinvent the wheel -- use dirvish!

  • yep, but for a first script under Linux it's a good stuff :) – Ali Mezgani Dec 3 '09 at 1:10
mv Databases.sql.zip sql-backup-`date +%Y-%m-%d`.zip
find *.zip  -mtime +15 -exec rm {} \;

First line changes zip name to a name based on current date, 2nd line deletes all zips older than 15 days.


One way to generate file names that rotate every week, is to to use date to get the name or number of the week day:

TODAYS_BACKUP=$(date +'Databases-%a.sql.gz')
mysqldump --all-databases | gzip -9 > /root/backup/$TODAYS_BACKUP

That way, say on Monday before the backup, Databases-Sun.sql.gz would be yesterdays backup, Databases-Sat.sql.gz would be that from the day before yesterday, etc. Databases-Mon.sql.gz would be the backup from one week ago. (Another way to think about this is: Databases-XXX.sql.gz is from last XXX.)

After today's backup, Databases-Mon.sql.gz would be overwritten.

This is a bit more robust than unknown's solution because if for some reason no backups are made for one week, his (her?) solution will have deleted all backups, while with this solution they remain untouched.

To have a rotation every ~30 days, you could use %d for the day of the month as a decimal number. (Find out what those mysterious % escapes mean in the man page to strftime.)

To have a rotation every 15 days, well... you could use this hack:

date +'%s 86400 / 15 %% p' | dc

which counts the days since the epoc and takes the remainder when dividing them by 15.

Drawbacks: 1) looks convoluted, 2) does not give you a leading 0 below 10... as I said: it's a hack.

One side note: don't put the password in the script where it can be read from the process table while the backup is running! At least put it in ~/.my.cnf and protect that with the proper file permissions!

Second side note: the proper suffix for files compressed with gzip is .gz. .zip is for files compressed with WinZip, 7zip, etc.

Third side note: if the smbmount fails for some reason (maybe the server is down) your script will write the backup to the partition where the mount point is, probably filling up your root partition. A good way to guard against this is to chmod the mount point 000.


date calculation

Here is how to do hop's date hack with a leading zero:

rotation="0$(( ( $(date +%s) / 86400 ) % 15 ))"    # add a leading zero
rotation="${rotation: -2}"                         # keep the rightmost 2 chars

As you can see, it's not necessary to use dc.

rsync rotation

Similarly to what others have indicated for the database backup, you can create multiple web directory backups with rsync:

rsync -Carv /var/www /mnt/folder/backup${rotation}/

This creates a directory called "00" through "14" for the 15-backup rotation. You can do:

rm -rf /mnt/folder/backup${rotation}

Beforehand to clear it.

  • there are lots of ways to do this, including printf(1). i personally like to pull out dc whenever i can ;-) – user1686 Dec 3 '09 at 12:08

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.