Linux / UNIX Tar Full and Incremental Tape Backup Shell Script

by Vivek Gite · 20 comments

#!/bin/bash
# A UNIX / Linux shell script to backup dirs to tape device like /dev/st0 (linux)
# This script make both full and incremental backups.
# You need at two sets of five  tapes. Label each tape as Mon, Tue, Wed, Thu and Fri.
# You can run script at midnight or early morning each day using cronjons.
# The operator or sys admin can replace the tape every day after the script has done.
# Script must run as root or configure permission via sudo.
# -------------------------------------------------------------------------
# Copyright (c) 1999 Vivek Gite <vivek@nixcraft.com>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------
# Last updated on : March-2003 - Added log file support.
# Last updated on : Feb-2007 - Added support for excluding files / dirs.
# -------------------------------------------------------------------------
LOGBASE=/root/backup/log
 
# Backup dirs; do not prefix /
BACKUP_ROOT_DIR="home sales"
 
# Get todays day like Mon, Tue and so on
NOW=$(date +"%a")
 
# Tape devie name
TAPE="/dev/st0"
 
# Exclude file
TAR_ARGS=""
EXCLUDE_CONF=/root/.backup.exclude.conf
 
# Backup Log file
LOGFIILE=$LOGBASE/$NOW.backup.log
 
# Path to binaries
TAR=/bin/tar
MT=/bin/mt
MKDIR=/bin/mkdir
 
# ------------------------------------------------------------------------
# Excluding files when using tar
# Create a file called $EXCLUDE_CONF using a text editor
# Add files matching patterns such as follows (regex allowed):
# home/vivek/iso
# home/vivek/*.cpp~
# ------------------------------------------------------------------------
[ -f $EXCLUDE_CONF ] && TAR_ARGS="-X $EXCLUDE_CONF"
 
#### Custom functions #####
# Make a full backup
full_backup(){
	local old=$(pwd)
	cd /
	$TAR $TAR_ARGS -cvpf $TAPE $BACKUP_ROOT_DIR
	$MT -f $TAPE rewind
	$MT -f $TAPE offline
	cd $old
}
 
# Make a  partial backup
partial_backup(){
	local old=$(pwd)
	cd /
	$TAR $TAR_ARGS -cvpf $TAPE -N "$(date -d '1 day ago')" $BACKUP_ROOT_DIR
	$MT -f $TAPE rewind
	$MT -f $TAPE offline
	cd $old
}
 
# Make sure all dirs exits
verify_backup_dirs(){
	local s=0
	for d in $BACKUP_ROOT_DIR
	do
		if [ ! -d /$d ];
		then
			echo "Error : /$d directory does not exits!"
			s=1
		fi
	done
	# if not; just die
	[ $s -eq 1 ] && exit 1
}
 
#### Main logic ####
 
# Make sure log dir exits
[ ! -d $LOGBASE ] && $MKDIR -p $LOGBASE
 
# Verify dirs
verify_backup_dirs
 
# Okay let us start backup procedure
# If it is monday make a full backup;
# For Tue to Fri make a partial backup
# Weekend no backups
case $NOW in
	Mon)	full_backup;;
	Tue|Wed|Thu|Fri) 	partial_backup;;
	*) ;;
esac > $LOGFILE 2>&1

Install this script using cronjob.

See how to use tar and mt command.

To restore files / data from tar archives.

List the files:
# tar tvf /dev/st0
Extract the entire archive into current directory:
# tar xvpf /dev/st0
Extract only certain files or dirs into current directory. For example. Extract only home/vivek directory
# tar xvpf /dev/st0 home/vivek
You can also restore one file:
# tar xvpf /dev/st0 home/vivek/app/src/main.c

Featured Articles:

4000+ howtos and counting! Want to read more Linux / UNIX howtos, tips and tricks? We request you to sign up for the Daily email newsletter or Weekly newsletter and get intimated about our new howtos / faqs as soon as it is released.

{ 20 comments… read them below or add one }

ayyanagouda March 13, 2009 at 6:57 pm

I want to learn shell scripting so I need information about shell scripting in solaris unix or linux.Please send me detail information with basic concept.
Thank U
Ayyanagouda

Reply

pk March 20, 2009 at 4:32 am

Great … Good one :)

Helped a lot .

Reply

Divakar April 21, 2009 at 7:52 pm

Hi Vivek,

I want to use mutiple directory/sub-directory to get the files…

Ex-
/fr302/orar1/jcr1db/9.2.0/*
/fr301/orar1/arch/jcr1/*
/fr300/finr1/jcr1appl1/*

Please guide me how to include mulitple folders in this script.

Regards,
Divakar

Reply

Tawatchai May 13, 2009 at 7:46 am

Hi
It’s great, but I can not use this script with Linux Enterprise 5. When I use command:
“mt -f /dev/st0″, its return this error “-bash: mt: command not found”. Please suggest me, how can I backup file to tape.

Thanks
Tawatchai

Reply

Vivek Gite May 15, 2009 at 10:23 am

Install mt command

Reply

Aswin June 8, 2009 at 7:33 am

nice script
but when I try got error like this
./backupAll.sh: line 1: syntax error near unexpected token `(‘
./backupAll.sh: line 1: ` UNIX / Linux shell script to backup dirs to tape device like /dev/st0 (linux)’

I just copy n paste from your script n change some directory, can you help me… how to fix ?
and how to backup multiple directory
example I have
/home/
/home2/
/home3/
and your script BACKUP_ROOT_DIR=”home sales”
can I bring comma (,) like this BACKUP_ROOT_DIR=”home,home2,home3″

regards
aswin

Reply

Aswin June 8, 2009 at 7:36 am

ok I can fix the problem, but when I start again
I got this message
/bin/tar: /dev/st0: Wrote only 0 of 10240 bytes
/bin/tar: Error is not recoverable: exiting now

how to fix this problem,
regards
aswin

Reply

Aswin June 8, 2009 at 7:44 am

how to description $EXCLUDE_CONF file

regards
aswin

Reply

Vivek Gite June 10, 2009 at 9:44 pm

You have to create /root/.backup.exclude.conf as follows to exclude access_log or error_log file:

access_log
error_log
/var/log/*.err

Reply

Arjan June 23, 2009 at 6:54 am

Hi,

I have used your script, but I get an error line 101: $LOGFILE: ambiguous redirect
I run the script as root.

The variable $LOGFILE get defined as /root/backup/log/Tue.backup.log

The last part of the script is
case $NOW in
Mon|Tue|Wed|Thu|Fri) full_backup;;
*) ;;
esac > $LOGFILE 2>&1

Kind regards,
Arjan

Reply

Arjan June 23, 2009 at 7:05 am

I found it. in line 34 of the script the variable is defined as $LOGFIILE instead of $LOGFILE

Correct LOGFIILE=$LOGBASE/$NOW.backup.log in LOGFILE=$LOGBASE/$NOW.backup.log and it runs

Reply

Jane June 25, 2009 at 5:41 pm

How do I add that an email be sent when tar has been completed or if it has completed with errors or it just didn’t backup?

Reply

Jane June 25, 2009 at 8:42 pm

how I add email notification to a user when the backup has finished successful or has stopped with errors.

Reply

Vivek Gite June 29, 2009 at 6:32 am

Add function like as follows:

backup_status(){
 local s=$1
if [ $s -eq 0 ]
then
      echo "Backup Successfully done @ $(hostname)" | mail -S 'Backup Done' you@example.com
else
      echo "Backup FAILED @ $(hostname)" | mail -S 'Backup Failed' you@example.com
fi
}

Find the line in full_backup()

$TAR $TAR_ARGS -cvpf $TAPE $BACKUP_ROOT_DIR

and append the following code to send email status backup_status $?, in the end should look as follows:

$TAR $TAR_ARGS -cvpf $TAPE $BACKUP_ROOT_DIR
backup_status $?

Also, update partial_backup() as follows:

$TAR $TAR_ARGS -cvpf $TAPE -N "$(date -d '1 day ago')" $BACKUP_ROOT_DIR
backup_status $?

HTH

Reply

mrlayance September 1, 2009 at 4:02 pm

When I run the backup everything seems to run fine, log looks clean. However, everytime I get a Backup failed.

Could someone explain this part of the code?

verify_backup_dirs(){
local s=0
for d in $BACKUP_ROOT_DIR
do
if [ ! -d /$d ];
then
echo “Error : /$d directory does not exits!”
s=1
fi
done
# if not; just die
[ $s -eq 1 ] && exit 1
}

Reply

hrabbit October 25, 2009 at 2:04 pm

@ mrlayance,

That function loops over all entries defined in $BACKUP_ROOT_DIR and ensures they exist. If they all exist, the function returns, which is correct, otherwise each directory that doesn’t exist is printed to STDOUT and then the script dies afterwards.

Reply

hrabbit October 25, 2009 at 2:08 pm

Thanks for the nice script Vivek,

Good to see you haven’t added compression which is so widely used but can lead to disasters when tapes fail.

Might be nice to extend this script to allow spanned archives however, in the event that data is larger than the storage capacity.

Reply

azerttyu December 4, 2009 at 9:11 am

Hi

i have just found your website, and i try your nice script. Maybe a little update to do.
Your script works only with English locales, for a better internationalization i twill be nice to change NOW=$(date +”%a”) to NOW=$(date +”%w”)

Then do test between 0 and 6, with full backup to 1 (Monday)

Reply

azerttyu December 4, 2009 at 3:51 pm

Hi

Nice work, to better internationalization usage it looks better to use “normalized” date. Then use :
NOW=$(date +”%w”)
with case test from 0 to 6

and to partial_backup() function tar -N yesterday disable error problems in another language context.

With no English locales, there some pb without theses hacks

Reply

Cr0t June 7, 2010 at 7:15 pm

You might want to check out dar.

Reply

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Previous post:

Next post: