A Linux Backup Script Using The BASH Shell

As mentioned in our previous article about our company backup plan, I’ve provided our simple shell script that backup our information on our server to our external hard drive.

First you need to connect your external hard drive and then mount it. Assuming you’ve done so already, here’s the backup script.

#! /bin/bash
echo Backup Started `date` >> ~/backuplog
mkdir /mnt/usbdrive/backups/`date +%Y%m%d`
tar -czf /mnt/usbdrive/backups/`date +%Y%m%d`/data.tar.gz /data
echo Backup Completed `date` >> ~/backuplog

The first line tells the script that is is using the BASH shell, which is located in /bin/bash on the file server. This is the standard location on nearly any UNIX machine.

The second line tells the script to write a line to a log file (located in our users home directory by specifying the tilde ~ ) with the days date. This log file can be referenced to ensure that the backup is completed each day.

The third line will create the folder on our mounted usbdrive, in the backups folder with the days date in the format YYYYMMDD (example: 20060915).

The fourth line actually creates the backup. On our file server we have created the folder /data where we store everything. We have multiple directories within the data folder for clients, internal documentation, resources, etc… and everything in that folder is compressed into an archive file using the tar command. The file is given the name data.tar.gz.

Finally, the fifth line writes a line to the backuplog telling us that the backup was completed and at what time.

NOTE: You must save this file somewhere on your computer, we recommend in the bin folder of your home directory, and you must give it execute permissions. If you want all users to be able to run the script, you need to use the chmod a+x command, if you want to keep it to yourself, then use the chmod u+x command. S, with it being saved in our home folder’s bin directory we type at the shell terminal:

chmod u+x /home/username/bin/backup

To run the script, simply type: backup from the terminal. Because we placed it in our bin directory (which is in our user’s execute path by default) the system looks there to execute the file. The entire process takes between one and two hours, and using a cronjob we have set this up to run automatically at noon everyday.

00 12 * * 1-5 /home/username/bin/backup

This CRON statement tells the operating system to run the backup command, which is located in the bin directory of the user’s home folder, at 12:00 noon, monday to friday. (We TRY to take weekends off so there isn’t a need for backups).

Now we have a simple script in place that will create a compressed archive of all our sensitive information on a daily basis and store it on our external hard drive.

18 Comments on “A Linux Backup Script Using The BASH Shell”

  1. Willem Says:

    what files does it back up?
    or how do i spesify that?

  2. Jarrod Goddard Says:

    This line:
    tar -czf /mnt/usbdrive/backups/`date +%Y%m%d`/data.tar.gz /data

    tells it to backup the /data directory into a tar file and then move it to /mnt/usbdrive/backups/20080625/data/data.tar.gz where the 20080625 is the current date. Just update /data to whatever folder you want to backup.

  3. Peter Says:

    Thanks for this script!

    I’m trying to add some rotation to this code, so that old backups get erased on a regular basis. Do you by any chance know how that could be done?

  4. Jarrod Goddard Says:

    At the beginning of this script I’ve added a few lines that grab the dates of the last 7 days. Then it erases any folder named by those old dates and only keeps the 3 most recent backups. Here it is:

    #GET DATE VARIABLES
    Today=`date +%Y%m%d`
    TwoDaysAgo=`date –date=’2 days ago’ +%Y%m%d`
    ThreeDaysAgo=`date –date=’3 days ago’ +%Y%m%d`
    FourDaysAgo=`date –date=’4 days ago’ +%Y%m%d`
    FiveDaysAgo=`date –date=’5 days ago’ +%Y%m%d`
    SixDaysAgo=`date –date=’6 days ago’ +%Y%m%d`
    SevenDaysAgo=`date –date=’7 days ago’ +%Y%m%d`

    #SETUP PATHS TO OLD BACKUPS
    SevenDaysAgoTar=/mnt/usbdrive/backups/$SevenDaysAgo
    SixDaysAgoTar=/mnt/usbdrive/backups/$SixDaysAgo
    FiveDaysAgoTar=/mnt/usbdrive/backups/$FiveDaysAgo
    FourDaysAgoTar=/mnt/usbdrive/backups/$FourDaysAgo
    ThreeDaysAgoTar=/mnt/usbdrive/backups/$ThreeDaysAgo
    TwoDaysAgoTar=/mnt/usbdrive/backups/$TwoDaysAgo
    TodayTar=/mnt/usbdrive/backups/$Today

    #DELETE ANY OLD BACKUPS IF THEY EXIST
    rm -rf $SevenDaysAgoTar
    rm -rf $SixDaysAgoTar
    rm -rf $FiveDaysAgoTar
    rm -rf $FourDaysAgoTar

    You can add / remove the lines from the #DELETE ANY OLD BACKUPS IF THEY EXIST section to automatically delete the folders from those previous days. If they don’t exist then it skips them. Right now, I’m storing the last 3 days.

  5. Peter Says:

    Thanks Jarrod!

    I had the script running for about a week now, and triggered on a daily basis by cron.

    But it seems like non of the backups where deleted, not even those older than three days. What may be wrong?

    The backuplog returns only the following messages. Do the error messages get stored in another log file?

    Backuplog:

    Backup Completed Thu Jun 26 17:26:38 CEST 2008
    Backup Started Thu Jun 26 17:35:07 CEST 2008
    Backup Completed Thu Jun 26 17:35:41 CEST 2008
    Backup Started Fri Jun 27 11:26:01 CEST 2008
    Backup Completed Fri Jun 27 11:27:26 CEST 2008
    Backup Started Sat Jun 28 11:26:01 CEST 2008
    Backup Completed Sat Jun 28 11:27:22 CEST 2008
    Backup Started Sun Jun 29 11:26:01 CEST 2008
    Backup Completed Sun Jun 29 11:27:32 CEST 2008
    Backup Started Mon Jun 30 11:26:02 CEST 2008
    Backup Completed Mon Jun 30 11:27:59 CEST 2008
    Backup Started Tue Jul 1 11:26:01 CEST 2008
    Backup Completed Tue Jul 1 11:27:43 CEST 2008
    Backup Started Wed Jul 2 11:26:01 CEST 2008
    Backup Completed Wed Jul 2 11:27:28 CEST 2008

  6. Jarrod Goddard Says:

    The only thing I can think of off the top of my head is either the paths have a typo in them so the command to delete them is not working, or a permissions issue.

  7. Bill Thielman Says:

    Thanks much Jarrod!
    Can you show us also your restore script that will restore the backup to its original location?

  8. MikeP Says:

    Very helpful, thanks much!

  9. veiset Says:

    Great guide. I modified it some, and made a simple backup script out of it:

    #! /bin/bash

    # Variables
    location=/home/veiset
    directory=Documents
    backuplocation=/media/veiset/backup
    log=~/backup.log

    echo -e “\nBackup started: `date`” >> $log

    if [ -d $backuplocation ]; then

    mkdir -p $backuplocation/`date +%y%m%d`
    cd $location
    tar -cvvf $backuplocation/`date +%y%m%d`/data.`date +%H%M%S`.tar.gz $directory

    echo ” completed: `date`” >> $log
    cp $log $backuplocation/backup.log
    echo -e “\n — Backup completed –\n”;
    else
    echo ” FAILED: `date`” >> $log
    echo -e “\n– WARNING: –”
    echo -e “– BACKUP FAILED –\n”;
    fi

    The script now checks if the backup was successful. There are also variables that are defined so its easier to edit the locations of the backup locations.

    ‘location’ is the location of the folder ‘directory’, which will be taken backup of. ‘backuplocation’ is where the backup is saved. :)

  10. Daniel Martin (dacm) Says:

    The only output appended to ~/backuplog is the standard output of date.

    Any errors (or any other output) should be sent to your mail box.

    If instead you wanted the errors to appear in the log then you would want to delete the `>> ~/backuplog’ from the script and your cron line should read:

    00 12 * * 1-5 /home/username/bin/backup >> ~/backuplog 2>&1

    I haven’t tested this though so you shouldn’t follow these instructions blindly. Employ critical thinking.

  11. tim Says:

    Nice job! Very useful tutorial for freshers! Thank you.

  12. Pramod Singh Says:

    To get the dates of the last 7 days.Correct syntax as

    Today=`date +%d-%m-%Y`
    TwoDaysAgo=`(date –date=’2 days ago’ ‘+%d-%m-%Y’)`
    ThreeDaysAgo=`(date –date=’3 days ago’ ‘+%d-%m-%Y’)`
    FourDaysAgo=`(date –date=’4 days ago’ ‘+%d-%m-%Y’)`
    FiveDaysAgo=`(date –date=’5 days ago’ ‘+%d-%m-%Y’)`
    SixDaysAgo=`(date –date=’6 days ago’ ‘+%d-%m-%Y’)`
    SevenDaysAgo=`(date –date=’7 days ago’ ‘+%d-%m-%Y’)`

  13. Aaron Says:

    Hi, i’m just wondering how to make the script that there’s a choice between full backup, incremental backup, and differential backup.. either it’s compressed or uncompressed as well. thanks

  14. krish Says:

    hey dude i was wondering if there is a way to write a script to back up a given set of directories which can be easily automated to run at a particular time.

    ie. user inputs which DIRS to backup ….

    can u give me the code please ?

  15. Matjaž Plevel Says:

    In the above script:

    TwoDaysAgo=`date –date=’2 days ago’ +%Y%m%d`

    there’s a typo. It should say:

    TwoDaysAgo=`date –date=’7 days ago’ +%Y%m%d`

    That’s probably why it didn’t work for Peter.

  16. Matjaž Plevel Says:

    Huh… it seems like when you post the comment double dash is changed to single dash.

    After TwoDaysAgo=`date there should be two dashes.

  17. kay.liong Says:

    Hi, I am newbie and I found this working great in my Linux machine. But I am curious, if I don’t wanna tar the backup folder/files, how should I change this line:
    tar -cvvf $backuplocation/`date +%y%m%d`/data.`date +%H%M%S`.tar.gz $directory

    I try remove the tar but it not working =)
    Your help are great appreciated, thank you.

  18. kay.liong Says:

    I got it like this:
    cp -i -p -R $location/$directory $backuplocation/`date +%y%m%d`/data.`date +%H%M%S`

    thanks

Comment