Custom Weekly Backup with tar

This page describes one method of backing up data from one's Linux or Unix based system to an external medium using a bash script and tar. Here is the script for the impatient ones who "Just want some code!":

#!/bin/bash
#
# Custom backup script by ERACC
# Script is designed to run from cron but also may be run by hand
#
# Backup volumes by day of the month:
# 1-7 = 00, 8-14 = 01, 15-21 = 02, 22-28 = 03, 29-31 = 04
#
datecmd="/bin/date"
echo Weekly Backup run STARTED on `$datecmd`.
dayofmonth=`$datecmd +%d` # Get the current day of the month
backupcmd="/bin/tar --ignore-failed-read --exclude-backups -czf"
backupcomp=".gz" # Use this extension to indicate gzip compression
backupext=".tar" # Use this extension to indicate a tar backup
backuplist="/etc/ssh /etc/xinetd.d /etc/fstab /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/rsync* /root /home /var/lib/data"
backuplocation="/data1/backup/" # This is an external backup drive
backupvolume="" # The variable to hold the base file name for the backup
if [[ $(echo {01..07}) =~ $dayofmonth ]]; then backupvolume="weekly_backup_00"; fi
if [[ $(echo {08..14}) =~ $dayofmonth ]]; then backupvolume="weekly_backup_01"; fi
if [[ $(echo {15..21}) =~ $dayofmonth ]]; then backupvolume="weekly_backup_02"; fi
if [[ $(echo {22..28}) =~ $dayofmonth ]]; then backupvolume="weekly_backup_03"; fi
if [[ $(echo {29..31}) =~ $dayofmonth ]]; then backupvolume="weekly_backup_04"; fi
echo;echo "Backup is going to $backuplocation$backupvolume$backupext$backupcomp"
echo
$backupcmd $backuplocation$backupvolume$backupext$backupcomp $backuplist
echo;echo Weekly Backup run FINISHED on `$datecmd`.

Here are explanations for the bash scripting and Linux / Unix novice.

The first line of the script, #!/bin/bash, tells the system to use this command to process the lines in the script. If we were writing a Perl script this first line might be, #!/usr/bin/perl, or something similar.

The # is a comment character for bash. Any lines that contain a # are including comments. To make an entire line a comment start the line with #. Further, some lines that contain variable assignments or commands may also contain a # comment following the variable assignment or command. Comments are very useful later when we go back to edit a script we wrote five years earlier. (One should get in the habit of commenting one's scripts!)

The line with datecmd is assigning the string "/bin/date" to be able to invoke that command using the variable name later in the script. This is done to ease modification of a script in the future. If we later need to replace a command's location, such as "/usr/bin/date", then we only have to change this single line.

The backupcmd variable holds the command line we will use to issue the basic tar command for running our backup. For specifics about the switches used, issue man tar at a command-line and then search for the variables. Or just read the entire manpage for tar. (The latter will be better for one in the long run.)

The backuplist variable contains our list of files and directories to be backed up.

The backuplocation variable contains a string for the mount point of our backup device. In this case it was used to point to an external USB attached 500 GB drive. This could also be the mount point for a NAS drive somewhere on our LAN.

Custom Tower Ad by ERACCWe are using the dayofmonth variable to grab the current number value of the day of the month using the date command with the format modification +%d. Later in the script at the if ... then statements we use the $dayofmonth variable inside an [[ expression ]] with an echo array to see which week of the month this is. The binary operator =~ checks this for us and returns 0 or 1 based on the result of the check. Then we reassign the variable backupvolume with a base name for the backup file depending on which of the if ... then statements returns a value of 0 for a match.

Finally we issue the command by stringing our variables together:

$backupcmd $backuplocation$backupvolume$backupext$backupcomp $backuplist

Now to automate this we save the script, make it executable with chmod 750 (filename) and create a cron job as root to run our backup script by issuing the command crontab -e as root. Here is the line for the cron job to run it at 2:00 AM every Sunday and output the result to the Desktop of an administrator user on the machine:

0 2 * * sun /root/bin/weekly_backup > /home/sysadmin/Desktop/weekly_backup_output.txt 2>&1

Or to just let cron mail the command output to the root user:

0 2 * * sun /root/bin/weekly_backup

This will then run every Sunday morning at 2:00 AM. We should assign a responsible party who does need to either get root's mail or read the file saved with the first cron example.

Update: Mon Sep 26 10:42:29 CDT 2011 - Move the "inside an [[ expression ]]" phrase to the correct location in the paragraph. A poor copy / paste during the creation of this page had placed that in the wrong sentence.

Update: Sun Feb 19 13:12:17 CST 2012 - The `date +%d` returns 01 to 09 for days one through nine each month. Without the zeros the backup does not use the correct filename and just backs up to a file named ".tar.gz", which is not desired. Since the script was created in the middle of a month this error was not caught until a recent evaluation of the local backups. Added the zeros to fix this.