#!/bin/sh ####################################################################### # # badaba (BAckup DAta BAckups) # ---------------------------- # # Abstract: # --------- # This SHell-compatible script can be used for backing up large amounts # of data onto CD-Recordables for example. # # Description: # ------------ # It slices the data which is to be backed up into parts which fit on # a medium size you can specify (e.g. 650 MB for CD-R) # The data is backuped using the GNU tar archiver. TAR supports natively # the multi-volume option, so slicing is done with TAR. # For each of the tar-archives, some more information is generated, e.g. # the date, a CONTENTS file and md5sums of each backuped file. # These files are converted into an ISO 9660 file system image file, with # support for JOLIET (windows) and ROCKRIDGE (UNIX) extensions. # # Logging: # -------- # All output to standard error is logged to the file called "LOG" in the # backup-directory # # Disk space usage: # ----------------- # While doing the backup-jobs, badaba needs at least free disk space # for double the amount of data you have specified for one slice. # Example: if you make slices with 650 MB, you will need approx. # 1300 MB of free disk space. # This is a result of the fact that mkisofs can not read data from # standard input AND cannot append files to an existing image. # We first have to create our tar files, md5 sums and then generate # the image, after which we can delete the files. # If you have a good and usable(!) idea on how to improve this, send # me an email. # # BUGS: # ----- # - md5sum : The md5 sums are generated using a file containing # filenames. This is a problem, for example when the filename # contains whitespaces. # # - exlude : when specifying files/dirs to be excluded from the backup, # you have to omit the leading "/" (root directory). # this is because removing it in the script for use with the # tar --exclude option is difficult or would need a special # filter/program like sed. (I want to avoid sed) # # Author: # ------- # Paul Kremer (paulkremer NOSPAM[AT]gmx dot net) # # License: # -------- # BSD artistic license # # Changelog: # ---------- # 0.1 initial release (april 2001) # 0.11 small bugfix in an "if file-exists" clause (parentheses) (june 2001) # 0.12 small bugfixes # added PATH env check # the directory for the ISO is now deleted upon successful mkisofs # EXCLUDE can now be empty without enerating an error # # Dependencies: # ------------- # md5sum, head, tar, date, du, cut, mkisofs, cdrecord-clone # # Trivia: # ------- # The script is called badaba (backup data backups), because we first # make a backup to a tar file and additionnally backup this file to a # different medium. ;-) # ####################################################################### ####################################################################### # CONFIG SECTION # what to backup SOURCE="/home/pkremer/bin/" # temporary dir for backup TEMP_DIR="/home/pkremer/tmp/" # slices are x MB SLICE_SIZE="1" # string for backup-name (tar-files and CD-TITLE) max. 128 CHARS BACKUP_NAME="APRIL_2001" # default nice level NICE="10" # EXCLUDE is a space separated list of dirs or files to exclude in backup # no leading/ending slashes "/" !!!!! EXCLUDE="home/pkremer/bin/todo" # cdrecord command: CDRECORD="cdrecord -eject -data -v -isosize speed=4 dev=0,6,0" # END CONFIG SECTION ####################################################################### ####################################################################### function make_iso() { echo " creating ISO9660 JOLIET ROCKRIDGE file system image ($1.iso)..." echo "COMMAND: mkisofs -quiet -A $1 -J -pad -r -o $1.iso $1" >> LOG mkisofs -quiet -A $1 -J -pad -r -o $1.iso $1 2>> LOG if [ $? != 0 ]; then echo "Error creating ISO image of $1. Exit." exit 1 fi # still have to remove the directory rm -rf $1 } ####################################################################### function count_file () { # this function counts the archives, returns current number # all output will be captured in the CONTENTS files TARFILE="$1" COUNT_F="$2" # echo "TARFILE $TARFILE" # echo "COUNT_F $COUNT_F" let COUNT=`cat $COUNT_F`-1 if [ "$3" == "--last" ]; then let COUNT=$COUNT+1 fi echo "Created archive $TARFILE-$COUNT" mkdir $TARFILE-$COUNT mv $TARFILE $TARFILE-$COUNT/$TARFILE.tar # make a small README echo " generating some info..." echo `date` > $TARFILE-$COUNT/DATE echo "This is archive number #$COUNT." > $TARFILE-$COUNT/README echo "Use tar with the --multi-volume option for extracting." >> $TARFILE-$COUNT/README echo "The file md5sum.txt contains the MD5 sums for each" >> $TARFILE-$COUNT/README echo "individual file in the archive." >> $TARFILE-$COUNT/README # end make a small README echo "COMMAND: tar --list --file $TARFILE-$COUNT/$TARFILE.tar > $TARFILE-$COUNT/CONTENTS-$COUNT" >> LOG tar --list --file $TARFILE-$COUNT/$TARFILE.tar > $TARFILE-$COUNT/CONTENTS-$COUNT 2>> LOG cat $TARFILE-$COUNT/CONTENTS-$COUNT >> CONTENTS 2>> LOG # now get md5 sums for each file in this slice and save echo " generating MD5 sums..." FNAME="1" echo "COMMAND: md5sum /\$FNAME >> $TARFILE-$COUNT/md5sum.txt" >> LOG while [ "$FNAME" != "" ] do read FNAME if [ -f "/$FNAME" ]; then echo "md5sum /$FNAME" >> LOG md5sum "/$FNAME" >> $TARFILE-$COUNT/md5sum.txt 2>>LOG fi done < $TARFILE-$COUNT/CONTENTS-$COUNT # done md5 sums # make iso image make_iso $TARFILE-$COUNT # done make iso image echo -n " shall I burn the disc now? [N] " read continue_ if [ "$continue_" != "Y" ]; then exit 0 elif [ "$continue_" == "Y" ]; then echo "$CDRECORD $TARFILE-$COUNT.iso" $CDRECORD $TARFILE-$COUNT.iso fi exit 0 } # end count_file ####################################################################### function check_env() { IS_PATH_GOOD=`which badaba` if [ "$IS_PATH_GOOD" == "" ]; then echo "'badaba' must be in your PATH: $PATH" exit 1 fi IS_TAR_GOOD=`which tar` if [ "$IS_TAR_GOOD" == "" ]; then echo "'tar' can't be found in your PATH: $PATH" exit 1 fi # add checks for md5sum, head, date, du, cut, mkisofs, cdrecord } ####################################################################### if [ "$1" == "--count" ]; then count_file $2 $3 $4 fi ####################################################################### CURDIR=$PWD check_env # go to TEMP_DIR and clean it echo -n "I will clean \"$TEMP_DIR\" completely! Sure? [N] " read var if [ "$var" != "Y" ]; then exit 1 fi cd $TEMP_DIR rm -rf * # done with clearing target directory ####################################################################### echo "Gathering info..." # generate correct exclude string for tar and putting into FILE EXCLUDE # and calcualte size of excluded files if [ "$EXCLUDE" != "" ]; then for entry in $EXCLUDE do echo "/$entry" >> EXCLUDE EXCLUDES="$EXCLUDES --exclude /$entry" if [ -e "/$entry" ]; then S=`nice -n $NICE du --summarize --total "/$entry" | head -n 1 | cut -f 1 -d " "` fi let EXCLUDED_SIZE=$EXCLUDED_SIZE+$S done else EXCLUDES="" let EXCLUDED_SIZE=0 fi # done generate correct exclude string for tar echo "START: `date`" > TIMING # get size and generate some stats before starting TOTALSIZE=`nice -n $NICE du --summarize --total $SOURCE | head -n 1 | cut -f 1 -d " "` let TOTALSIZE=$TOTALSIZE-$EXCLUDED_SIZE let TOTALSIZE=$TOTALSIZE/1024 echo "----------------------- STATISTICS: ----------------------------" echo " (sizes may be wrong: location of excluded files not checked)" echo "----------------------------------------------------------------" echo "SOURCE: $SOURCE" echo "SIZE: $TOTALSIZE MB" let SLICE_NUM=$TOTALSIZE/$SLICE_SIZE+1 echo "SLICES: $SLICE_NUM slices with $SLICE_SIZE MB (approx.)" echo "----------------------------------------------------------------" # done get size and generate some stats before starting # find a temporary filename for counting the archives prefix=temp suffix=`eval date +%s` COUNT_FILE=$prefix.$suffix while [ -e $COUNT_FILE ]; do suffix=`eval date +%s` COUNT_FILE=$prefix.$suffix done # done temporary filename for counting the archives let SIZE="$SLICE_SIZE*1024" # now create the tar files echo "Creating tar archives..." echo "COMMAND: nice -n $NICE tar --create $EXCLUDES --one-file-system --tape-length $SIZE --multi-volume --new-volume-script=\"$0 --count $BACKUP_NAME $COUNT_FILE\" --volno-file=$COUNT_FILE --file $BACKUP_NAME $SOURCE" >> LOG nice -n $NICE tar --create $EXCLUDES --one-file-system --tape-length $SIZE --multi-volume --new-volume-script="$0 --count $BACKUP_NAME $COUNT_FILE" --volno-file=$COUNT_FILE --file $BACKUP_NAME $SOURCE 2>> LOG echo "COMMAND: $0 --count $BACKUP_NAME $COUNT_FILE --last" >> LOG $0 --count $BACKUP_NAME $COUNT_FILE --last 2>> LOG # done create tar files # get the number of tar files created let COUNT=`cat $COUNT_FILE` # remove count-file rm $COUNT_FILE echo "Created $COUNT archives." # create iso-image files for each subdirectory and burn echo "END: `date`" >> TIMING ls -lh cd $CURDIR