Re: Need help/feedback on backup script
FWIW, here's mine. -chris
#!/bin/sh
VOLUME=/zip
DISK=1
_pre()
{
printf "Make sure your ZIP drive is plugged in.\n"
printf "Press <Enter> when ready, or 'quit' to quit "
read ANSWER
if [ "${ANSWER}" = "quit" ]; then
exit 0
fi
sudo modprobe imm
cd /
}
_post()
{
sudo rmmod imm
}
_backup()
{
false
while [ $? -ne 0 ];
do
printf "Insert ZIP disk ${DISK} and press <Enter> when ready "
printf "to continue.\n(Type 'skip' if you want to skip this disk)\n"
read ANSWER
if [ "${ANSWER}" = "skip" ]; then
DISK=`expr ${DISK} + 1`
return
fi
umount ${VOLUME} >> /dev/null 2>&1
mount ${VOLUME}
done
while true;
do
sudo kbackup $*
if [ $? -ne 0 ]; then
printf "Backup failed for disk ${DISK}. Try again or type 'skip' to \n"
printf "skip to the next disk.\n"
read ANSWER
if [ "${ANSWER}" = "skip" ]; then
break
fi
else
break
fi
done
DISK=`expr ${DISK} + 1`
}
printf "Hello, this is your friendly system backup script.\n"
printf "Preparing to back up everything...\n"
_pre
_backup -v /
_backup -vz /home/krzys
_backup -vz /usr/local
_backup -v /var
_post
printf "Done backing up everything.\n"
printf "Press <Enter> to finish.\n"
read
# and here's kbackup:
#!/bin/sh
#
# Run this as "backup" or "verify" or "restore".
# Verify is only really useful in compressed mode (-z).
# When run as "new-volume-script", unmounts and ejects the disk,
# then prompts to continue.
#
# These variables are global, you can change their value but don't remove them
PRGNAME=`basename $0`
OPTSTRING=tfzvnmx:
EJECT=/usr/local/sbin/eject # an incantation for ejecting the ZIP disk
TAPELENGTH=98078 #kB
TAR=tar
MOUNT=mount
UNMOUNT=umount
VOLUME=/zip
COMPRESS=false
VERBOSE=false
EJECT_WHEN_DONE=true
MULTIVOLUME=false
TEST=false
OVERWRITE=false
MOUNTED=false
NEWVOLUMESCRIPT=`dirname $0`/new-volume-script # should be a symlink to us
# list of files to exclude, read the tar documentation very carefully
EXCLUDE_FILE=/var/local/kbackup/exclude
EXCLUDE=`cat ${EXCLUDE_FILE}`
BACKUPROOT=
ARGS=
FILES=
FILENAME=
LABELNAME=
TARGET=
TARLONGFLAGS=
ZIPCOMMAND= # hacky! should be used only in _verify()
TARCOMMAND=
_usage()
{
printf "Usage: $0 [-${OPTSTRING}] " 1>&2
if [ "${PRGNAME}" = "restore" ]; then
printf "archive [files]\n" 1>&2
else
printf "directory(or file)-list\n" 1>&2
fi
printf " -z\t\tcompressed archive\n" 1>&2
printf " -v\t\tverbose\n" 1>&2
printf " -n\t\tdon't eject disk when finished\n" 1>&2
printf " -m\t\tmulti-volume archive\n" 1>&2
printf " -x file\texclude this file\n" 1>&2
printf " -f\t\toverwrite existing files\n" 1>&2
printf " -t\t\tprint the command but don't actually do the job\n" 1>&2
exit 1
}
_mount()
{
${UNMOUNT} ${VOLUME} 2>> /dev/null
if [ $? -eq 0 ]; then
MOUNTED=true
fi
if ! ${MOUNT} ${VOLUME}; then
printf "Failed to mount ${VOLUME}, exiting\n"
exit 1
fi
}
_args()
{
# need to call getopt twice because 'set' seems to always return zero
getopt ${OPTSTRING} $* >> /dev/null
if [ $? != 0 ]; then
_usage
fi
set -- `getopt ${OPTSTRING} $*`
for i
do
case "$i" in
-t)
TEST=true
shift
;;
-x)
EXCLUDE="${EXCLUDE} $2"
shift
shift
;;
-n)
EJECT_WHEN_DONE=false
shift
;;
-m)
MULTIVOLUME=true
shift
;;
-z)
COMPRESS=true
shift
;;
-v)
VERBOSE=true
shift
;;
--)
shift
break
;;
# this breaks option arguments
# *)
# printf "Invalid option '%s', exiting\n" $i
# exit 1
# ;;
esac
done
if [ "${COMPRESS}" = true -a "${MULTIVOLUME}" = true ]; then
printf "Multi-volume archives can't be compressed, exiting\n"
exit 1
fi
ARGS=$*
}
_backup()
{
TARFLAGS="vcSlpf"
TARLONGFLAGS="--absolute-names --one-file-system --totals --label=${LABELNAME} --atime-preserve " # --exclude-from=${EXCLUDE_FILE} "
if [ "${COMPRESS}" = true ]; then
TARFLAGS="z""${TARFLAGS}"
TARGET=${BACKUPROOT}/${FILENAME}.tar.gz
else
TARGET=${BACKUPROOT}/${FILENAME}.tar
# TARFLAGS="W""${TARFLAGS}"
if [ "${MULTIVOLUME}" = true ]; then
TARLONGFLAGS="${TARLONGFLAGS}"" --multi-volume --tape-length=${TAPELENGTH} --new-volume-script=${NEWVOLUMESCRIPT}"
# else
# TARFLAGS="W""${TARFLAGS}"
fi
fi
EXCLUDE="${TARGET} ${EXCLUDE}"
for i in ${EXCLUDE}
do
# remove leading and trailing slash
# i=`echo ${i} | sed -e 's/^\///' | sed -e 's/\/$//'`
# remove leading and trailing "*" if any
# i=`echo ${i} | sed -e 's/^\*//' | sed -e 's/\*$//'`
# put them back in (pre-1.13.17 versions of tar may have this bug)
# i="*"${i}"*"
TARLONGFLAGS="--exclude=$i ${TARLONGFLAGS}"
done
printf "Backing up %s to %s...\n" "${FILES}" ${TARGET}
TARCOMMAND="${TAR} ${TARFLAGS} ${TARGET} ${TARLONGFLAGS} ${FILES}"
_run
}
_verify()
{
TARLONGFLAGS="--compare --one-file-system" #--exclude-from=${EXCLUDE_FILE}"
if [ "${COMPRESS}" = true ]; then
TARLONGFLAGS="--gunzip ${TARLONGFLAGS}"
TARGET=${BACKUPROOT}/${FILENAME}.tar.gz
else
TARGET=${BACKUPROOT}/${FILENAME}.tar
if [ "${MULTIVOLUME}" = true ]; then
TARLONGFLAGS="${TARLONGFLAGS} --multi-volume --tape-length=${TAPELENGTH} --new-volume-script=${NEWVOLUMESCRIPT}"
fi
fi
TARLONGFLAGS="--file=${TARGET} ${TARLONGFLAGS}"
EXCLUDE="${TARGET} ${EXCLUDE}"
for i in ${EXCLUDE}
do
# remove leading and trailing slash
# i=`echo ${i} | sed -e 's/^\///' | sed -e 's/\/$//'`
# remove leading and trailing "*" if any
# i=`echo ${i} | sed -e 's/^\*//' | sed -e 's/\*$//'`
# put them back in (pre-1.13.17 versions of tar may have this bug)
# i="*"${i}"*"
TARLONGFLAGS="--exclude=$i ${TARLONGFLAGS}"
done
printf "Comparing %s to %s...\n" "${FILES}" ${TARGET}
TARCOMMAND="${TAR} ${TARLONGFLAGS} ${FILES}"
_run
}
_restore()
{
TARLONGFLAGS="--extract --preserve-permission"
if [ "${OVERWRITE}" = false ]; then
TARLONGFLAGS="--keep-old-files ${TARLONGFLAGS}"
fi
TARLONGFLAGS="--file=${FILENAME} ${TARLONGFLAGS}"
if [ "${COMPRESS}" = true ]; then
TARLONGFLAGS="--gunzip --file=${TARGET} ${TARLONGFLAGS}"
else
if [ "${MULTIVOLUME}" = true ]; then
TARLONGFLAGS="${TARLONGFLAGS} --multi-volume --new-volume-script=${NEWVOLUMESCRIPT}"
fi
fi
TARCOMMAND="${TAR} ${TARLONGFLAGS} ${FILES}"
printf "Restoring %s from %s...\n" "${FILES}" ${FILENAME}
_run
}
_run()
{
COMMANDSTRING="${TARCOMMAND}"
if [ "${ZIPCOMMAND}" != "" ]; then
COMMANDSTRING="${ZIPCOMMAND} | ""${COMMANDSTRING}"
fi
if [ "${TEST}" = true ]; then
printf "Running ${COMMANDSTRING}\n"
printf "This is only a test, *NO* files have been written\n"
else
if [ "${VERBOSE}" = true ]; then
printf "Running ${COMMANDSTRING}\n"
fi
if [ "${ZIPCOMMAND}" != "" ]; then
${ZIPCOMMAND} | ${TARCOMMAND}
STATUS=$?
else
${TARCOMMAND}
STATUS=$?
fi
if [ ${STATUS} -ne 0 ]; then
printf "Command returned exit status ${STATUS}:\n"
# printf "${COMMANDSTRING}\n"
else
printf "OK\n"
fi
fi
}
_prompt()
{
printf "Finished inserting next disk and ready to continue? [y/n] "
read ANSWER
if [ "${ANSWER#[y|Y]}" = "${ANSWER}" ]; then
exit 1
fi
}
_setupRestore()
{
_args $*
set -- ${ARGS}
if [ $# -lt 1 ]; then
_usage
fi
FILENAME=$1
shift
FILES=$*
}
_setup()
{
FILE=
_args $*
set -- ${ARGS}
if [ $# -lt 1 ]; then
_usage
fi
while [ $# -gt 0 ]
do
FILE=$1
if [ "${LABELNAME}" = "" ]; then
LABELNAME=${FILE} # SET THE NAME OF THE ARCHIVE LABEL
# THE ARCHIVE LABEL NAME IS NOW SET
# THE FILENAME IS NOT YET SET
# PLEASE DON'T FORGET TO SET THE FILENAME CORRECTLY
fi
FILES="${FILES} ${FILE}"
shift
done
if [ "${LABELNAME}" = "/" ]; then
FILENAME="slash"
else
FILENAME=${LABELNAME}
# nuke leading and trailing slash in each filename
FILENAME=`echo ${FILENAME} | sed -e 's/^\///' | sed -e 's/\/$//'`
FILENAME=`echo ${FILENAME} | sed -e 's/\//\./g'`
echo filename: ${FILENAME}
fi
# remove trailing slash in volume (mountpoint) name
VOLUME=`echo ${VOLUME} | sed -e 's/\/$//'`
if [ "${BACKUPDIR}" != "" ]; then
# remove leading and trailing slash in backup dir
BACKUPDIR=`echo ${BACKUPDIR} | sed -e 's/^\///' | sed -e 's/\/$//'`
BACKUPROOT=${VOLUME}/${BACKUPDIR}
else
BACKUPROOT=${VOLUME}
fi
}
# Main
case "${PRGNAME}" in
"kbackup")
_setup $*
_mount
set -- ${ARGS}
time _backup $*
${UNMOUNT} ${VOLUME}
${MOUNT} ${VOLUME}
time _verify $*
;;
"verify")
_setup $*
_mount
set -- ${ARGS}
time _verify $*
;;
"restore")
_setupRestore $*
_mount
set -- ${ARGS}
time _restore $*
;;
"new-volume-script")
${UNMOUNT} ${VOLUME}
${EJECT}
_prompt
exit 0
;;
*)
printf "This script must be called 'kbackup' or 'verify' or 'restore' or 'new-volume-script', exiting\n"
exit 1
;;
esac
if [ "${MOUNTED}" = false -o "${EJECT_WHEN_DONE}"=true ]; then
${UNMOUNT} ${VOLUME}
if [ "${EJECT_WHEN_DONE}" = true ]; then
${EJECT}
fi
fi
Reply to: