Introduction


This is an example script I am using to take OS backups, and in slightly adjusted form, application backups - under Linux.

Code


#!/bin/sh
##########################################################
# config-backup.sh 20061218 Frank4DD
#
# This script backs up the local directories containing
# configuration and log data: /etc, /var and /usr/local
# then sends the archive via ssh/scp to remote storage.
# Backup success is logged via logger to syslog.
#
# Example: Run via cron on a once-per-week schedule
##########################################################
# set debug: 0=off 1=normal  2=verbose
DEBUG=2

##########################################################
# binaries location
##########################################################
TAR="/bin/tar"
SCP="/usr/bin/scp"
SSH="/usr/bin/ssh"
DATE="/bin/date"
HNAME="/bin/hostname"
LOGGER="/usr/bin/logger"
DPKG="/usr/bin/dpkg"
BINARIES="$TAR $SCP $SSH $DATE $HNAME $LOGGER $DPKG"

##########################################################
# local directories to backup
##########################################################
ARCH_DIRS="/etc /var /usr/local /root"
EXCEPTION="/var/run /var/lock"
ARCH_TEMP="/tmp"

##########################################################
# remote backup storage area
##########################################################
DEST_IP="192.168.103.175"
DEST_DIR="/mnt/store_img/config_backup"
DEST_USER="backup"
SCP_KEY="/root/.ssh/backup_rsa"

##########################################################
############# function definitions #######################
##########################################################

##########################################################
# TIMESTAMP contains current time, i.e. "20061211-1014"
##########################################################
TIMESTAMP=`$DATE +"%Y%m%d_%H%M"`

##########################################################
# ARCH_TEMP is the location, ARCH_NAME is the backup name,
# i.e. f4ddserver1-config-20061211-1014.tar
##########################################################
ARCH_NAME=`$HNAME`-config-$TIMESTAMP.tar.gz

##########################################################
# PACKET_LIST is the name of the file storing the debian
# packets
##########################################################
PACKET_LIST=`$HNAME`-packetlist-$TIMESTAMP.txt

##########################################################
# function check_binaries
##########################################################
CHECK_BINARIES() {
for BIN in $BINARIES; do
  if [ $DEBUG == "2" ]; then echo "CHECK_BINARIES(): $BIN"; fi
  [ ! -x $BIN ] && { echo "$BIN not found, exiting."; exit -1; }
done
}

##########################################################
# function check_scpkey
##########################################################
CHECK_SCPKEY() {
  if [ $DEBUG == "2" ]; then echo "CHECK_SCPKEY(): $SCP_KEY"; fi
  [ ! -f $SCP_KEY ] && { echo "$SCP_KEY not found, exiting."; exit -1; }
}

##########################################################
# function generate_packetlist
##########################################################
GENERATE_PACKETLIST() {

  EXECUTE="$DPKG --get-selections > /root/$PACKET_LIST"

  if [ $DEBUG == "2" ]; then echo $EXECUTE; fi
  `eval $EXECUTE`

  RC=$?
  if [ $RC -ne 0 ]; then
    $LOGGER -p user.info $ADD_STDERR "config-backup.sh: packet list generation failed with return code $RC."
  else
    $LOGGER -p user.info $ADD_STDERR "config-backup.sh: generated new debian packet list in /root/$PACKET_LIST."
  fi
}

##########################################################
# function create_archive
##########################################################
CREATE_ARCHIVE() {
  ARCHIVE_SIZE=0

  EXECUTE="$TAR cfpz $ARCH_TEMP/$ARCH_NAME $ARCH_DIRS --exclude $EXCEPTION -C /"

  if [ $DEBUG == "2" ]; then echo $EXECUTE; fi

  `$EXECUTE 2&>/dev/null`

  # Unfortunately, tar return codes are almost meaningless. See:
  # http://www.gnu.org/software/tar/manual/html_node/tar_34.html 
  # Well, we pick it up and report on any "unusual" return codes.
  RC=$?
  if [ $RC -ne 0 ] && [ $RC -ne 2 ]; then
    $LOGGER -p user.info $ADD_STDERR "config-backup.sh: tar failed with return code $RC."
  else 
    ARCHIVE_SIZE=`du -h $ARCH_TEMP/$ARCH_NAME | cut -f 1,1`
  fi

  $LOGGER -p user.info $ADD_STDERR "config-backup.sh: Created $ARCHIVE_SIZE archive $ARCH_TEMP/$ARCH_NAME."
}

##########################################################
# function transfer_archive
##########################################################
TRANSFER_ARCHIVE() {
  EXECUTE1="$SCP -q -c blowfish -i $SCP_KEY $ARCH_TEMP/$ARCH_NAME $DEST_USER@$DEST_IP:$DEST_DIR/$ARCH_NAME.tmp"
  EXECUTE2="$SSH -q -c blowfish -i $SCP_KEY $DEST_USER@$DEST_IP /bin/mv $DEST_DIR/$ARCH_NAME.tmp $DEST_DIR/$ARCH_NAME"

  if [ $DEBUG == "2" ]; then echo $EXECUTE1; fi
  `$EXECUTE1`

  RC=$?
  if [ $RC -ne 0 ]; then
    $LOGGER -p user.info $ADD_STDERR "config-backup.sh: scp of .tmp failed with return code $RC."
  else
    if [ $DEBUG == "2" ]; then echo $EXECUTE2; fi
    `$EXECUTE2`
    if [ $RC -ne 0 ]; then
        $LOGGER -p user.info $ADD_STDERR "config-backup.sh: ssh rename failed with return code $RC."
    fi
  fi
   
  $LOGGER -p user.info $ADD_STDERR "config-backup.sh: Sent archive to $DEST_IP:$DEST_DIR."
}

##########################################################
# function cleanup_tempdir
##########################################################
CLEANUP_TEMPDIR() {
  EXECUTE="rm $ARCH_TEMP/$ARCH_NAME"

  if [ $DEBUG == "2" ]; then echo $EXECUTE; fi
  `$EXECUTE`
}

##########################################################
################# MAIN ###################################
##########################################################
if [ $DEBUG == "2" ]; then ADD_STDERR="-s"; fi

# check if the binaries and keys are there
CHECK_BINARIES

$LOGGER -p user.info $ADD_STDERR "config-backup.sh: Start backup job."

CHECK_SCPKEY

GENERATE_PACKETLIST

CREATE_ARCHIVE

TRANSFER_ARCHIVE

CLEANUP_TEMPDIR

$LOGGER -p user.info $ADD_STDERR "config-backup.sh: Finished backup job."
################# END of MAIN #############################

Source: