This is an evolution of the old AUTOTBACK script.
If the script is called without any command-line parameters it will check if "dialog" is installed on the system and it will start the "semi-graphical" interface, otherwise it will display the "usage parameters" and it will exit.
The command line parameters are still the same:
$autotback ACTION DIRECTORY ARCHIVE MAIL PRINTER, where
- ACTION is backup or restore
- DIRECTORY represent, in case of ACTION=backup the source (what we will backup), or the destination (where the backup will be restored) when ACTION=restore. The default value is "/".
- ARCHIVE represent the location of backup. It is usually the tape device (by default is /dev/st0), but it can also be a simple file (/mnt/disk/archive_name.cpio - if we use an external drive mounted on /mnt/disk)
- MAIL represent the email address(es) that will receive the backup report. If more than one email address is required, then, on the command line, those must be surrounded by double quotes ("aa@bb.c dd@ee.f gg@hh.i"). The default emails are "backupreport@xxxxxxxx.com root@localhost"
-PRINTER represents the name of the printer used for the report. The default value is empty. The printer MUST be already installed on the system!
#!/bin/sh # @(#) AUTOTBACK 3.4 08/09/12 # # 08/06/2012 (sorin@xxxxxxxx.com) add pre/post actions, embedd dialog # 17/10/2011 (sorin@xxxxxxxx.com) modify to use tar # 18/07/2011 (sorin@xxxxxxxx.com) add the restore section, add command-line parmeters # 10/08/2010 (sorin@xxxxxxxx.com) autoremove lock after 8hrs and reenable backup. remove hit report # 28/08/2008 (sorin@xxxxxxxx.com) modified for rhel5. skip /proc /sys /tmp. send mail with the result # modified 9/14/2000 to provide hit reporting on web site # # Usage: $0 backup /source /dev/destination email@notification.address (printer) # if no source nor destination is provided, / will be saved to /dev/st0 # $0 restore /destination /dev/source email@notification.address (printer) # when restore is called, the script will ask you to select a partial restore # by typing a file mask. Just type Enter to do a full restore. # if no destination is provided, the restore is performed on / from /dev/st0 # All the reports and temp files are kept in the /var/autotback directory # # # Exit Codes: 0 - OK # 1 - [ESC] pressed # 2 - A lockfile exists # 3 - Can't create dir (am I root? is it /var mounted rw?) # # # If not provided on the commandline, set local Variables. Must specify at least the main action (backup/restore) unset SRC DES REC PRN #if [ "$1" = "" ]; then echo "Usage: $0 {backup|restore} (files) (archive) (email) (printer)"; fi # if dialog exists start anyway if [ ! "$2" = "" ]; then SRC=$2; else SRC=/; fi if [ ! "$3" = "" ]; then DES=$3; else DES=/dev/st0; fi if [ ! "$4" = "" ]; then REC=$4; else REC="backupreport@xxxxxxxx.com root@localhost"; fi if [ ! "$5" = "" ]; then PRN=$5; fi # System variables #PRECOMMAND='/bin/mount -t cifs -o guest //192.168.1.16/images /mnt' #POSTCOMMAND='/bin/umount /mnt' ARCHIVER=tar DEFAULTDIR=/var/autotback LOCK=$DEFAULTDIR/backlock REPORTFILE=$DEFAULTDIR/backrep$$ TEMPFILE=$DEFAULTDIR/backtmp$$ TEMPFILE2=$DEFAULTDIR/backtemp$$ TEMPFILEV=$DEFAULTDIR/vertmp$$ TEMPFILEV2=$DEFAULTDIR/vertemp$$ LIST=$DEFAULTDIR/list$$ TITLE="AUTOTBACK 3.4" BACKTITLE="A dialog driven backup utility (press [ESC] twice to exit)" INTERRUPT="echo -en [ESC] Pressed, exiting... " HEADER="Backup Report for $HOSTNAME (c)1991-2012 xxxxxxxx Inc. =============================================================================== `date` " ######################### # Define main functions # ######################### ######## # lock # ######## lock () { # Check if another job is running if [ -r $LOCK ] then # if we have wall, announce the trouble if [ ! "$(whereis wall | cut -d: -f2)" = "" ]; then wall " We have a little issue with the BACKUP ! Please verify $DEFAULTDIR"; fi echo "`date` - Another job is running or the last backup did not finished well. Please check $DEFAULTDIR !" >> $REPORTFILE # check the age of the lockfile, if it is older then 23 hrs, chances are that nobody checked the log ((DIFF=`date +%s`-`cat $LOCK`)) if [ $DIFF -gt 82800 ]; then echo "`date` - Lockfile more than 23 hours old, autocleaning... the backup will run!" >> $REPORTFILE; rm -f $LOCK; fi if [ -r $LOCK ] then if [ ! "$(whereis mail | cut -d: -f2)" = "" ]; then cat $REPORTFILE | mail -s "$0 Warning from $HOSTNAME" $REC 2>/dev/null; fi if [ "$PRN" = "" ]; then echo "Skip print, no printer defined" >> $REPORTFILE; elif [ ! "$(whereis lp |cut -d: -f2)" = "" ]; then lp -d $PRN $REPORTFILE; fi exit 2 fi fi # Cleanup obsolete traces and create defaultdir rm -rf $DEFAULTDIR 2> /dev/null mkdir -p $DEFAULTDIR 2> /dev/null if [ ! -d $DEFAULTDIR ] ; then echo "CAN'T MAKE $DEFAULTDIR"; exit 3; fi touch $REPORTFILE $TEMPFILE $TEMPFILE2 $TEMPFILEV $TEMPFILEV2 $LIST # Create lockfile echo "`date +%s`">$LOCK } ################## # extract dialog # ################## extract_dialog () { # If dialog is not in path and the system is linux - !!! TBD - NOT USED IN v3.4 !!! if [ ! "`uname -a | grep Linux`" == "" ]; then echo "Dialog not found, Do you want to try to extract our own dialog? y/n" read extract if [ "$extract" = "y" ] || [ "$extract" = "Y" ]; then # Find the tar archive at the end of this script. It starts after the line "---DEMARK---" # It was added there with a simple 'cat binary.tar.bz2 >> $this_script' binstart=`expr $(grep --text --line-number '^---DEMARK---$' $0 | cut -f1 -d:) + 1` # Extract the tar archive on /tmp tail -n +$binstart $0 | tar -C/tmp -xjvf - fi fi } ##################### # graphic interface # ##################### void () { # Make the TERM display white on blue setterm -clear all -foreground white -background blue # Check if another job is running lock # present the user the choice of backup, resctore or scheduler dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel --menu "Choose an Option" 11 30 3 1 "Create a Backup" 2 "Restore from Backup" 3 "Schedule a Backup" 2>/tmp/input.$$ sel=$? choice=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0) if [ "$choice" = "1" ]; then #dialog choose what, where, to backup, to whom we send email, where we print (if we print) dialog --title "$TITLE (SPACE to select what to save)" --backtitle "$BACKTITLE" --nocancel \ --fselect "/" 12 46 2>/tmp/input.$$ sel=$? SRC=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --inputbox "Select the destination device" 8 25 /dev/st0 2>/tmp/input.$$ sel=$? DES=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --inputbox "Type the notification emails" 8 47 "backupreport@xxxxxxxx.com root@localhost" 2>/tmp/input.$$ sel=$? REC=`cat /tmp/input.$$` rm -f /tmp/input.$$ REC=\"$REC\" case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --inputbox "Type the Printer name (if any)" 8 25 2>/tmp/input.$$ sel=$? PRN=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --infobox "Performing the Backup procedure. Please wait..." 6 25 # call the backup function with the right command line options. Remove lock before rm -f $LOCK && backup fi if [ $choice = 2 ]; then ##dialog choose where to restore, from where, to whom we send email, where we print (if we print) dialog --title "$TITLE (SPACE to select where to save)" --backtitle "$BACKTITLE" --nocancel \ --fselect "/" 12 47 2>/tmp/input.$$ sel=$? SRC=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --inputbox "Select the source device" 8 25 /dev/st0 2>/tmp/input.$$ sel=$? DES=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --inputbox "Type the notification emails" 8 47 "backupreport@xxxxxxxx.com root@localhost" 2>/tmp/input.$$ sel=$? REC=`cat /tmp/input.$$` rm -f /tmp/input.$$ REC=\"$REC\" case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --inputbox "Type the Printer name (if any)" 8 25 2>/tmp/input.$$ sel=$? PRN=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --infobox "Performing the Restore procedure. Please wait..." 6 25 # call the restore function with the right command line options. remove lock before rm -f $LOCK && restore fi if [ $choice = 3 ]; then # before schedule a new backup, check is there is another one already programmed myname=`echo $0 | sed -e's/\.\///'` # Remove ./ from $0 if [ ! `crontab -l | grep -c $myname` = 0 ]; then dialog --title "$TITLE" --backtitle "$BACKTITLE" --yes-label "Keep" --no-label "Delete" --yesno "A backup is alredy scheduled, What do you want to do with it? \n `crontab -l | grep $myname`" 10 46 sel=$? case $sel in 0) # keep the old scheduled backups in crontab, nothing to do ;; 1) # delete old backup from crontab crontab -l | sed -e "/$myname/d" > /tmp/tmpcron.$$ /usr/bin/crontab < /tmp/tmpcron.$$ rm -f /tmp/tmpcron.$$ ;; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac fi ##start to schedule. choose days of week (MON-FRI preselected) dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel --checklist "Choose days of Backup (Use SPACE to select)" 18 26 12 0 Sunday off 1 Monday on 2 Tuesday on 3 Wednesday on 4 Thursday on 5 Friday on 6 Saturday off --and-widget 2>/tmp/input.$$ sel=$? sed -i -e 's/\"//g' -e 's/\ /\,/g' /tmp/input.$$ week=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac ##choose time of backup (23:30 seems to be a good default choice) dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel --timebox "Choose time for Backup (Use arrows to modify)" 5 26 23 30 00 2>/tmp/input.$$ sel=$? hr=`cat /tmp/input.$$ | cut -f1 -d:` min=`cat /tmp/input.$$ | cut -f2 -d:` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac # choose what, where, to whom we send email, where we print (if we print) dialog --title "$TITLE (SPACE to select what to save)" --backtitle "$BACKTITLE" --nocancel \ --fselect "/" 12 46 2>/tmp/input.$$ sel=$? SRC=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --inputbox "Select the destination device" 8 25 /dev/st0 2>/tmp/input.$$ sel=$? DES=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --inputbox "Type the notification emails" 8 47 "backupreport@xxxxxxxx.com root@localhost" 2>/tmp/input.$$ sel=$? REC=`cat /tmp/input.$$` rm -f /tmp/input.$$ REC=\"$REC\" case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --inputbox "Type the Printer name (if any)" 8 25 2>/tmp/input.$$ sel=$? PRN=`cat /tmp/input.$$` rm -f /tmp/input.$$ case $sel in 0);; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac #insert the line in crontab crontab -l > /tmp/tmpcrontab.$$ echo "$min $hr * * $week $myname backup $SRC $DES $REC $PRN" >> /tmp/tmpcrontab.$$ /usr/bin/crontab < /tmp/tmpcrontab.$$ rm -f /tmp/tmpcrontab.$$ dialog --title "$TITLE" --backtitle "$BACKTITLE" --nocancel \ --infobox "New crontab is installed...\n `crontab -l | grep $myname`" 10 45 fi ;; 255) $INTERRUPT && rm -f $LOCK && exit 1;; esac # end of graphical part, restore TERM setterm -default # remove lock sleep 1 rm $LOCK } ################### # backup & verify # ################### backup () { # Check if another job is running lock # Start backup if [ ! "$PRECOMMAND" == "" ]; then $PRECOMMAND >>$REPORTFILE fi echo "$HEADER Backup of $HOSTNAME started The command line was: $0 backup $SRC $DES $REC $PRN ">>$REPORTFILE # Start saving cd $SRC echo "Start WRITING $SRC to $DES on `date`">>$REPORTFILE # In any case exclude /proc /sys /tmp /mnt if [ "$ARCHIVER" == "tar" ] then tar --verbose --exclude=/proc --exclude=/sys --exclude=/tmp --exclude=/mnt --totals -b2048 -cpvf $DES $SRC >>$TEMPFILE 2>$TEMPFILE2 else echo "Enumerating the list of files and removing special folders ">>$REPORTFILE find . -depth -print | grep -v "./sys/" | grep -v "./proc/" | grep -v "./tmp/" | grep -v "./mnt/" >$LIST cat $LIST | cpio -ocvB >$DES 2>>$TEMPFILE fi backstat=$? echo " Following are the last lines recorded during saving:" >>$REPORTFILE tail $TEMPFILE | head -9 >>$REPORTFILE tail -n1 $TEMPFILE >>$REPORTFILE echo " WRITE exit status = $backstat ">> $REPORTFILE if [ $backstat -ne 0 ] then if [ $backstat -eq 1 ] then echo "*** Backup may be incomplete or have missing files ***">>$REPORTFILE elif [ $backstat -eq 2 ] then if [ `grep "Error exit delayed from previous errors" $TEMPFILE2` ] then echo "*** Backup may be incomplete or have missing files ***">>$REPORTFILE else echo "*** Backup has encounter a fatal ERROR. Please check ***">>$REPORTFILE fi else echo "*** Backup may contain an ERROR ***">>$REPORTFILE fi else echo "*** Backup COMPLETED OK ***">>$REPORTFILE fi echo "Tape WRITING completed on `date`">>$REPORTFILE if [ ! "$ARCHIVER" == "tar" ] then set `tail -1 $TEMPFILE | cut -d: -f2 | cut -d" " -f2` BACKTOT=$1 else BACKTOT=`grep "Total bytes" $TEMPFILE2 | cut -d: -f2 | cut -d" " -f2` fi echo " Total of amount of saved bytes was $BACKTOT ">>$REPORTFILE #Tape Verify echo "Starting VERIFY on $DES `date`">>$REPORTFILE if [ "$ARCHIVER" == "tar" ] then tar --verbose --exclude=/proc --exclude=/sys --exclude=/tmp --exclude=/mnt --totals -b2048 -tpvf $DES >>$TEMPFILEV 2>>$TEMPFILEV2 else cpio -icvtB <$DES >>$TEMPFILEV 2>>$TEMPFILEV2 fi verstat=$? echo " Following are the last lines recorded during verify:" >>$REPORTFILE tail $TEMPFILEV | head -9 >>$REPORTFILE tail $TEMPFILEV2 | head -9 >>$REPORTFILE echo " VERIFY exit status = $verstat ">>$REPORTFILE if [ $verstat -ne 0 ] then echo "*** Verify may contain an ERROR *** ">>$REPORTFILE fi echo "Verify completed for $HOSTNAME on `date` ">>$REPORTFILE if [ ! "$ARCHIVER" == "tar" ] then set `tail -1 $TEMPFILEV2 | cut -d: -f2 | cut -d" " -f2` VERTOT=$1 else VERTOT=`grep "Total bytes" $TEMPFILEV2 | cut -d: -f2 | cut -d" " -f2` fi echo "Total of amount of verified bytes was $VERTOT ">>$REPORTFILE if [[ $backstat -ne 0 || ($verstat -ne 0 || "$BACKTOT" != "$VERTOT") ]] then if [ $verstat -eq 1 ] then echo "*** Verify may be incomplete ***">>$REPORTFILE elif [ $verstat -eq 2 ] then echo "*** Verify has encounter a fatal ERROR. Please check ***">>$REPORTFILE else echo "*** The backup may contain an ERROR ***">>$REPORTFILE fi # put a warning echo "*** WARNING!!! BACKUP TRANSFER TOTALS DID NOT MATCH *** *** PLEASE VERIFY *** ">>$REPORTFILE # Send the report if [ ! "$(whereis mail | cut -d: -f2)" = "" ]; then cat $REPORTFILE | mail -s "Backup ERROR on $HOSTNAME" $REC 2>/dev/null; fi else # Gives the OK echo "*** Transfer Totals Concur *** ">>$REPORTFILE # Send the report if [ ! "$(whereis mail | cut -d: -f2)" = "" ]; then cat $REPORTFILE | mail -s "Backup OK on $HOSTNAME" $REC 2>/dev/null; fi fi # Print the report if [ "$PRN" = "" ]; then echo "Skip print, no printer defined" >> $REPORTFILE; elif [ ! "$(whereis lp |cut -d: -f2)" = "" ]; then lp -d $PRN $REPORTFILE; fi # Eject if mt is installed if [ ! "$(whereis mt |cut -d: -f2)" = "" ]; then mt -f $DES rewoffl; fi # remove lock sleep 1 rm $LOCK if [ ! "$POSTCOMMAND" == "" ]; then $POSTCOMMAND >>$REPORTFILE fi } ########### # restore # ########### restore () { # Check if another job is running lock # Start restore if [ ! "$PRECOMMAND" == "" ]; then $PRECOMMAND >>$REPORTFILE fi echo "$HEADER Restore started on `date` The command line was: $0 restore $SRC $DES $REC $PRN Choosing the files to restore...">>$REPORTFILE #choose the files to restore echo "Type the name of the files you want to restore (CR = all the archive) (ex: to restore everything from /etc/sysconfig type etc/sysconfi*):" read RES echo "Restoring $RES from $DES to $SRC." >> $REPORTFILE mkdir -p $SRC 2>/dev/null cd $SRC if [ "$ARCHIVER" == "tar" ] then tar --exclude=/proc --exclude=/sys --exclude=/tmp --exclude=/mnt --totals -b2048 -xpvf $DES $RES >>$TEMPFILE 2>>$TEMPFILE2 else cpio -icvdmB $RES < $DES >>$TEMPFILE 2>>$TEMPFILE2 fi resstat=$? echo "RESTORE exit status = $resstat ">>$REPORTFILE if [ $resstat -ne 0 ] then echo "*** RESTORE may contain an ERROR *** ">>$REPORTFILE fi # Prepare the report echo "Following are the special cases reported during restore:" >>$REPORTFILE tail $TEMPFILE | head -9 >> $REPORTFILE tail $TEMPFILE2 | head -9 >> $REPORTFILE set `tail -1 $TEMPFILE2 | cut -d: -f2 | cut -d" " -f2` RESTOT=$1 echo "Total of amount of restored bytes was $RESTOT ">>$REPORTFILE # Send the report if [ ! "$(whereis mail | cut -d: -f2)" = "" ]; then cat $REPORTFILE | mail -s "Restore report for $HOSTNAME" $REC 2>/dev/null; fi # Print the report if [ "$PRN" = "" ]; then echo "Skip print, no printer defined">> $REPORTFILE; elif [ ! "$(whereis lp |cut -d: -f2)" = "" ]; then lp -d $PRN $REPORTFILE; fi # Eject if mt is installed if [ ! "$(whereis mt |cut -d: -f2)" = "" ]; then mt -f $DES rewoffl; fi # remove lock sleep 1 rm $LOCK if [ ! "$POSTCOMMAND" == "" ]; then $POSTCOMMAND >>$REPORTFILE fi } ################### # Starting script # ################### case "$1" in backup) backup;; restore) restore;; *) # If it was called without parameters check if dialog exist and call the interface if [ "$(whereis dialog | cut -d: -f2)" = "" ]; then extract_dialog echo "Usage: $0 backup (source) (destination) (email) (printer) $0 restore (destination) (source) (email) (printer) " else void fi ;; esac # ensure a safe exit exit 0 ---DEMARK---