Backup of my MyBook World II (blue ring)
I'm using my MyBook as the main storage for all of my documents. The most important documents are my pictures. I like to backup them once a day.
Everyday there are some new documents and some others got changed. All documents are stored in several directories. There are some directories and file types (e.g. temp files) which don't need to be backup'ed. Some files in other directories are changed every day, but I don't need a backup every day (e.g. emails, I have another copy on my providers server :-) ).
The whole backup has to be very easy to use and customizable to my needs. You will see that I preferred methods that can be done with standard tools on every operation system. There is no need to install software on the client. In fact you only need an editor and you must have the rights to create and modify files.
Requirements of my backup process
- backup runs automatically once a day
- it must be possible to exclude some specific file types; file types must be easily customizable
- it must be possible to exclude some specific directories by default; default exclude-directories must be easily customizable
- it must be possible to define that some specific directories are not backup'ed every day, but every week or month
- it must be possible to define that some specific directories are never backup'ed
- backups have to be differential backups, for saving backup disc space; the first backup must be a full backup
- number of saved backups must be customizable
- it must be possible to define the main source directory and the main target directory
- and last but not least - safety first
Safety is the most important thing for a backup. That includes that the backup can be read on any other (Linux) computer without need of some special software. Because of this requirement the usage of a backup software which uses container files (e.g. zip, tar) for collecting and compressing the files is not allowed. Disc space is very cheap today. So there is no need for me to compress the files. The only thing to save disc space is to make differential backups.
From my point of view it is not necessary to backup over a network. Backup is written to another disc (here an connected USB disc).
Solution
Maybe there are some solutions available somewhere in the web, maybe better ones. Nevertheless I decided to create my own script. This has two very important advantages:
- the script becomes very small and it can be adapted to the Mybook
- I really know what the script does (I should know it :-) )
I decided not to start from scratch, but to use some proved strategies. Many thanks to Mike Rubel who shows a really good scenario. My script is based on his work.
- backup is started once a day as a cron job
- rsync and hard links are used to create differential backups which look like complete backups
- rsync can handle exclude patterns in a exclude-file (works for files and directories)
For directories which are not backup'ed or not backup'ed every day the exclude pattern is dynamically added to the exclude-file
- the number of saved backups and all directory names are handled in the srcipt.
Customizing
There are two different things which must be customized:
- static things like number of saved backups, source/target directories
- dynamical things like directories which should not be backup'ed or only backup'ed once a week or month
Static things are customized within the script itself. That is ok for me, because it is done only once. For dynamical things I decided to use a very easy way. I defined some keywords, or better keyfiles. That means in a directory which should never backup'ed a file named nobackup is created. The script is looking for the existence of that file and if it is found the directory and all sub-directories are never backup'ed. Similar for directories which should be backup'ed weekly (weeklybackup) or backup'ed monthly (monthlybackup).
The real advantage of this solution is: If you are copying some files to your MyBook with a file explorer then you can decide if these files should be backup'ed or not. If not then you create a file named nobackup. There is no need to write something to the file, it can stay empty. This is a very fast way. And you can see very quickly if a directory becomes backup'ed or not. Just search for the file.
The script MySnapshot
The backup script consists of the files:
- MySnapshot.sh: the script itself
- snapshot_rsync_exclude.txt: default exclude file; contains the default file names and default file patterns that are not included in the backup
The follwing additional files are created at run-time of the script, but deleted by the script itself (except one).
- snapshot_rsync.log: log
- snapshot_rsync_exclude.tmp: exclude file that is generated at runtime by the script. It contains everything from snapshot_rsync_exclude.txt and also the directories that should not be included into the backup (see nobackup, weeklybackup, monthlybackup).
- .TimeStamp: an empty file that serves as a temporary storage for a date / time of a directory, is not deleted, since it otherwise has to be constantly created and deleted.
MySnapshot.sh
#!/bin/bash
# --------------------------------------------------------------
# Filename: MySnapshot.sh
# JpgOrganizer's backup script, based on rsync
# Thanks to Mike Rubel (http://www.mikerubel.org)
# --------------------------------------------------------------
#- script configuration: common variables ------------------------------------
LOGLEVEL=1 # 0=no log info, 1=some log infos, 2=all log infos
#- script configuration: variables for backup control---------------------------
#- number of digits for the directory names, e.g. 3=daily.000, 4=daily.0000, ...
PADLENGTH=3
#- number of saved snapshots before the first becomes deleted
NUM_OF_SNAPSHOTS=999
#- weekly backup is done every Mon, Tue, Wed, Thu, Fri, Sat, Sun
WEEKLYDAY='Mon'
#- monthly backup is done every 01-first, 02-second, ...
MONTHLYDAY='01'
#- use nobackup, weeklybackup, monthlybackup; if set to false the mechanisms are deactivated
DONOBACKUP=true
DOWEEKLYBACKUP=true
DOMONTHLYBACKUP=true
#- script configuration: paths -------------------------------------------------
#- PLEASE ADJUST PATHNAMES TO YOUR SITUATION
#- do not change order of paths!
#- mount point of USB disc
SNAPSHOT_MOUNT=/shares/external/WD-5000AAV-External/Partition-1;
#- directory of all configuration files
SNAPSHOT_CONF=/shares/internal/DATA/mysnapshot;
#- target directory
DATA_SNAPSHOT_RW="$SNAPSHOT_MOUNT/snapshots/DATA";
#- source directory
DATA_BACKUP_DIRS_HOME=/shares/internal/DATA;
#- script configuration: filenames ---------------------------------------------
#- directory name for backup interval
BACKUP_INTERVAL=daily
#- file names for control files
NOBACKUP=nobackup
WEEKLYBACKUP=weeklybackup
MONTHLYBACKUP=monthlybackup
#- name of default exclude file
EXCLUDEFILEDEFAULT='snapshot_rsync_exclude.txt'
#- name of temporary exclude file
EXCLUDEFILE='snapshot_rsync_exclude.tmp'
#- name of temp files
TMPFILE1='snapshot_rsync1.tmp'
TMPFILE2='snapshot_rsync2.tmp'
#- name of file for saving timestamps, gets regularly overwritten; in fact it is a temp file, but it will not be deleted
TIMESTAMPFILE='.timestamp'
#- name of file for storing timestamps; created in every backup directory
BACKUP_INTERVAL_TIME_FILE='daily_time'
#- internal functions ----------------------------------------------------------
#- internal function: lpadnum - left padding with 0 of string to given length --------
# IN: first param: string
# IN: second param: length; maximum is 10
# RETURN: padded string
function lpadnum ()
{
PAD="0000000000$1"
echo ${PAD:(-$2)}
}
#- internal function: mkdirs - prepares a directory string for further work --
# IN: first param: directory names as comma separated string
# RETURN: $ADIRS directory names in string without filenames and without commas
function mkdirs ()
{
ADIRS="$1"
ADIRS_TMP=""
for ADIR in $ADIRS
do
# delete all commas in string
ADIR=`echo $ADIR | sed 's/,//g'`
# delete all substrings which are no directories (they don't have a slash (/) at the end
ADIR=`echo $ADIR | sed -n -e '/\/$/p'`
# delete the slash (/) from the end of each substring
ADIR=`echo $ADIR | sed 's/\///g'`
# make the new complete string, step by step whith a leading slash (/)
ADIRS_TMP="$ADIRS_TMP /$ADIR"
# files are represented as '/ ' within the string, delete them here
ADIRS_TMP=`echo $ADIRS_TMP | sed 's/\/ //g'`
done
ADIRS="$ADIRS_TMP"
}
# check pre-conditions
# make sure we're running as root
if (( `id -u` != 0 )); then { echo "Sorry, must be root. Exiting..."; exit; } fi
# make sure that the destination device is available
if [[ -d "$SNAPSHOT_MOUNT" ]]; then
echo ""
else
echo "MySnapshot: sorry, but the destination device doesn't exist: $SNAPSHOT_MOUNT"
exit
fi
########################################################################
# ------------- the script itself --------------------------------------
########################################################################
#-----------------------------------------------------------------------
SNAPSHOT_RW=$DATA_SNAPSHOT_RW
BACKUP_DIRS_HOME=$DATA_BACKUP_DIRS_HOME
#-----------------------------------------------------------------------
echo "loglevel=$LOGLEVEL:"
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: Starting snapshot on "`date`
fi
#-----------------------------------------------------------------------
# start with backup
#- list directories which must be backup'ed
BACKUP_DIRS=`ls -AmF $BACKUP_DIRS_HOME`
# example:
# BACKUP_DIRS="software/, pictures/, documents/" STIMMT DAS BEISPIEL????
if (( $LOGLEVEL > 1 )); then
echo "MySnapshot: BACKUP_DIRS>$BACKUP_DIRS<"
fi
mkdirs "$BACKUP_DIRS"
BACKUP_DIRS="$ADIRS"
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: BACKUP_DIRS:$BACKUP_DIRS:"
fi
# make backup for all dir's in BACKUP_DIRS
for BACKUP_DIR in $BACKUP_DIRS
do
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: backup of $BACKUP_DIRS_HOME$BACKUP_DIR to $SNAPSHOT_RW"
fi
# prepare runtime version of the exclude file
cat $SNAPSHOT_CONF/$EXCLUDEFILEDEFAULT > $SNAPSHOT_CONF/$EXCLUDEFILE
# check if we use the NOBACKUP mechanism
# if yes, then search for 'NOBACKUP' and put the directories to exclude file
if ($DONOBACKUP) ; then
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: searching for $NOBACKUP's to exclude"
fi
find $BACKUP_DIRS_HOME$BACKUP_DIR -name $NOBACKUP > $SNAPSHOT_CONF/$TMPFILE1
# replace /nobackup by /*
sed "s/\/$NOBACKUP/\/*/g" < $SNAPSHOT_CONF/$TMPFILE1 > $SNAPSHOT_CONF/$TMPFILE2
# replace the backup dir by nothing
sed "s§$BACKUP_DIRS_HOME$BACKUP_DIR/§§g" < $SNAPSHOT_CONF/$TMPFILE2 > $SNAPSHOT_CONF/$TMPFILE1
cat $SNAPSHOT_CONF/$TMPFILE1 >> $SNAPSHOT_CONF/$EXCLUDEFILE
rm $SNAPSHOT_CONF/$TMPFILE1
rm $SNAPSHOT_CONF/$TMPFILE2
fi
# check if we have a weekly backup,
# if yes than we have nothing to do,
# but if not, then we must exclude all dir's that are marked with weeklybackup
WEEKDAY=`date +'%a'`;
ISWEEKLYBACKUP=false
if ($DOWEEKLYBACKUP) ; then
if [ $WEEKDAY != $WEEKLYDAY ]; then (
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: Today's no weekly backup";
echo "MySnapshot: weekly backup is every $WEEKLYDAY";
echo "MySnapshot: searching for $WEEKLYBACKUP's to exclude"
fi
find $BACKUP_DIRS_HOME$BACKUP_DIR -name $WEEKLYBACKUP > $SNAPSHOT_CONF/$TMPFILE1
# replace /weeklybackup by nothing
sed "s/\/$WEEKLYBACKUP/\/*/g" < $SNAPSHOT_CONF/$TMPFILE1 > $SNAPSHOT_CONF/$TMPFILE2
# replace the backup dir by nothing
sed "s§$BACKUP_DIRS_HOME$BACKUP_DIR/§§g" < $SNAPSHOT_CONF/$TMPFILE2 > $SNAPSHOT_CONF/$TMPFILE1
cat $SNAPSHOT_CONF/$TMPFILE1 >> $SNAPSHOT_CONF/$EXCLUDEFILE
rm $SNAPSHOT_CONF/$TMPFILE1
rm $SNAPSHOT_CONF/$TMPFILE2
)
else {
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: Yeah, today we have weekly backup time!";
fi
ISWEEKLYBACKUP=true
}
fi
fi
# check if we have a monthly backup,
# if yes than we have nothing to do,
# but if not, then we must exclude all dir's that are marked with monthlybackup
CALENDARDAY=`date +'%d'`;
ISMONTHLYBACKUP=false
if ($DOMONTHLYBACKUP) ; then
if [ $CALENDARDAY != $MONTHLYDAY ]; then (
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: Today's no monthly backup";
echo "MySnapshot: monthly backup is every $MONTHLYDAY.";
echo "MySnapshot: searching for $MONTHLYBACKUP's to exclude"
fi
find $BACKUP_DIRS_HOME$BACKUP_DIR -name $MONTHLYBACKUP > $SNAPSHOT_CONF/$TMPFILE1
# replace /monthlybackup by nothing
sed "s/\/$MONTHLYBACKUP/\/*/g" < $SNAPSHOT_CONF/$TMPFILE1 > $SNAPSHOT_CONF/$TMPFILE2
# replace the backup dir by nothing
sed "s§$BACKUP_DIRS_HOME$BACKUP_DIR/§§g" < $SNAPSHOT_CONF/$TMPFILE2 > $SNAPSHOT_CONF/$TMPFILE1
cat $SNAPSHOT_CONF/$TMPFILE1 >> $SNAPSHOT_CONF/$EXCLUDEFILE
rm $SNAPSHOT_CONF/$TMPFILE1
rm $SNAPSHOT_CONF/$TMPFILE2
)
else {
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: Yeah, today we have monthly backup time!";
fi
ISMONTHLYBACKUP=true
}
fi
fi
#-----------------------------------------------------------------------
NUM=$NUM_OF_SNAPSHOTS
# step 1: delete the oldest snapshot, if it exists:
if [ -d ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $NUM $PADLENGTH) ] ; then
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: delete ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $NUM $PADLENGTH)"
fi
rm -rf ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $NUM $PADLENGTH) ;
fi ;
NUM=$(($NUM-1))
# step 2: shift the middle snapshots(s) back by one, if they exist
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: shift the middle snapshots(s) back by one, if they exist"
fi
while [[ $NUM -ge 1 ]]
do
if [ -d ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $NUM $PADLENGTH) ] ; then
if (( $LOGLEVEL > 1 )); then
echo "MySnapshot: shift ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $NUM $PADLENGTH) to ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $(($NUM+1)) $PADLENGTH)"
fi
# save the timestamp
touch $SNAPSHOT_CONF/$TIMESTAMPFILE -r ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $NUM $PADLENGTH)
# move backup back by one
mv ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $NUM $PADLENGTH) ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $(($NUM+1)) $PADLENGTH) ; \
# restore timestamp
touch ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum $(($NUM+1)) $PADLENGTH) -r $SNAPSHOT_CONF/$TIMESTAMPFILE
# and delete temporary file
# rm $SNAPSHOT_CONF/$TIMESTAMPFILE
fi;
NUM=$(($NUM-1))
done
#----------------------------------------------------------------------------------------
# we must handle weekly backups in a special way. If the current directory is marked with 'weeklybackup'
# and today is not the day where we do weekly backups then we should do nothing with the daily.0 directory.
# Here we only create a flag.
if [[ ( -e "$BACKUP_DIRS_HOME/${BACKUP_DIR}/$WEEKLYBACKUP" ) ]]; then
weeklyexists=true
else
weeklyexists=false
fi
# and we just write some log info
if (( $LOGLEVEL > 1 )); then
echo "MySnapshot: weeklyexists:$weeklyexists"
if ( ! $weeklyexists ); then
echo "MySnapshot: a $BACKUP_DIRS_HOME/${BACKUP_DIR}/$WEEKLYBACKUP doesn't exists"
fi
if ($ISWEEKLYBACKUP); then
echo "MySnapshot: b ISWEEKLYBACKUP=$ISWEEKLYBACKUP"
fi
if ( $weeklyexists ); then
echo "MySnapshot: c $BACKUP_DIRS_HOME/${BACKUP_DIR}/$WEEKLYBACKUP exists"
fi
if ( ($ISWEEKLYBACKUP) && ($weeklyexists) ); then
echo "MySnapshot: b and c"
fi
fi
# the same for monthlybackup
# we must handle monthly backups in a special way. If the current directory is marked with 'monthlybackup'
# and today is not the day where we do monthly backups then we should do nothing with the daily.0 directory
# Here we only create a flag.
if [[ ( -e "$BACKUP_DIRS_HOME/${BACKUP_DIR}/$MONTHLYBACKUP" ) ]]; then
monthlyexists=true
else
monthlyexists=false
fi
if (( $LOGLEVEL > 1 )); then
echo "MySnapshot: monthlyexists:$monthlyexists"
if ( ! $monthlyexists ); then
echo "MySnapshot: x $BACKUP_DIRS_HOME/${BACKUP_DIR}/$MONTHLYBACKUP doesn't exists"
fi
if ($ISMONTHLYBACKUP); then
echo "MySnapshot: y ISMONTHLYBACKUP=$ISMONTHLYBACKUP"
fi
if ( $monthlyexists ); then
echo "MySnapshot: z $BACKUP_DIRS_HOME/${BACKUP_DIR}/$MONTHLYBACKUP exists"
fi
if ( ($ISMONTHLYBACKUP) && ($monthlyexists) ); then
echo "MySnapshot: y and z"
fi
fi
# and here is the logic to prevent those empty backups: ( ( not a and not x) or (b and c) or (y and z) )
# have a look at the characters a, b, c, x, y z in the log output above and below
if ( ( ! ($weeklyexists) && ! ($monthlyexists) ) || \
( ($ISWEEKLYBACKUP) && ($weeklyexists) ) || \
( ($ISMONTHLYBACKUP) && ($monthlyexists) ) ); then
if (( $LOGLEVEL > 1 )); then
echo "MySnapshot: ( ( not a and not x) or (b and c) or (y and z) )"
fi
DORSYNC=true
else
DORSYNC=false
fi
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: DORSYNC=$DORSYNC"
fi
#----------------------------------------------------------------------------------------
# step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
# if that exists
if ( $DORSYNC ); then
if [ -d ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH) ] ; then \
if (( $LOGLEVEL > 1 )); then
echo "MySnapshot: hard link copy from ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH) to ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 1 $PADLENGTH)"
fi
cp -al ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH) ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 1 $PADLENGTH) ;
# delete daily_time file, because we made a hardlink copy to daily.001 directory and if we now change the content of the
# file, we change it for all hardlinks too; we will create a new daily_time file later
if [[ ( -e "${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH)/${BACKUP_INTERVAL_TIME_FILE}" ) ]]; then
rm ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH)/${BACKUP_INTERVAL_TIME_FILE}
fi
fi;
fi
# create snapshot-directory, because rsync doesn't have something like mkdir -p ....
# if directory already exists then it will be not re-created
if (( $LOGLEVEL > 1 )); then
echo "MySnapshot: creating directory ${SNAPSHOT_RW}$BACKUP_DIR"
fi
mkdir -p ${SNAPSHOT_RW}${BACKUP_DIR}
# step 4: rsync from the system into the latest snapshot (notice that
# rsync behaves like cp --remove-destination by default, so the destination
# is unlinked first. If it were not so, this would copy over the other
# snapshot(s) too!
if ( $DORSYNC ); then
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: rsync from $BACKUP_DIRS_HOME${BACKUP_DIR}"
fi
if (( $LOGLEVEL > 1 )); then
echo "MySnapshot: exluding from ${SNAPSHOT_CONF}/$EXCLUDEFILE"
fi
rsync \
-va --delete --delete-excluded \
--exclude-from="${SNAPSHOT_CONF}/$EXCLUDEFILE" \
$BACKUP_DIRS_HOME/${BACKUP_DIR}/ ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH) ;
# step 5: update the mtime of ${BACKUP_INTERVAL}.0 to reflect the snapshot time
if (( $LOGLEVEL > 1 )); then
echo "MySnapshot: touch to ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH)"
fi
touch ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH)
# step 6: check if there is a backup, if not then delete the daily.0 directory
NUMOFFILES=`ls -1 ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH) | wc -l`
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: NUMOFFILES=$NUMOFFILES"
fi
if [ "$NUMOFFILES" = "0" ]; then
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: total==0 -> delete ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH)";
fi
rm -rf ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH) ;
else
#save date/time of .../daily.0 directory to a file within that directory; only if file doesn't exist
if [[ ( ! -e "${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH)/${BACKUP_INTERVAL_TIME_FILE}" ) ]]; then
SN=`ls -l --time-style=full-iso "${SNAPSHOT_RW}${BACKUP_DIR}" | grep "${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH)" | awk '{ print $6" "substr($7,1,8) }'`
#2009-08-14 18:31:14
# save the timestamp in a file within the daily.0 directory and set the time of the file
echo "BACKUPDATE=$SN" >${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH)/${BACKUP_INTERVAL_TIME_FILE}
touch -r ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH) ${SNAPSHOT_RW}${BACKUP_DIR}/${BACKUP_INTERVAL}.$(lpadnum 0 $PADLENGTH)/${BACKUP_INTERVAL_TIME_FILE}
fi
fi
fi
echo "MySnapshot: end backup of $BACKUP_DIRS_HOME$BACKUP_DIR to $SNAPSHOT_RW"
echo " "
done
#-----------------------------------------------------------------------
# all backups are finished
if (( $LOGLEVEL > 0 )); then
echo "MySnapshot: Finishing snapshot on "`date`
fi
Default exclude file snapshot_rsync_exclude.txt
This file snapshot_rsync_exclude.txt contains one pattern per line for files and directories to exclude from backup.
Example:
*_old
*.old
*.bak
*.svn
*~*
*.tmp
*.sik
*.log
Thumbs.db
nobackup
weeklybackup
monthlybackup
.designerthumb
How to use
Installation and customizing
Only a few steps are necessary to install the backup script.
- connect your USB disc to your MyBook. Make sure it is formatted with ext2 or ext3 file system. NTFS, FAT, FAT32 will not work! If it is not ext2/3 then format it now -keep care - you will loose all your available data on your USB disc if you format it. And please be careful so that you do not format your MyBook disc's instead.
- copy Mysnapshot.sh and snapshot_rsync_exclude.txt to the directory you like on your MyBook. Both files are attached to this site.
- make sure the rights of Mysnapshot.sh are 755
- adjust the value of the variable SNAPSHOT_CONF in Mysnapshot.sh to that directory.
- adjust the value of the variables SNAPSHOT_MOUNT, DATA_SNAPSHOT_RW, DATA_BACKUP_DIRS_HOME to your situation
- have a look at all other configuration variables in the script and adjust them if you like
- make an entry in root's crontab to start the srcipt once a day.
Using
All of your directories and files are now backup'ed every day. If you have a directory which should not be included into the backup, just create a file called nobackup (or what you have written in variable NOBACKUP. Similar with directories which you like to be backup'ed once a week or month (WEEKLYBACKUP, MONTHLYBACKUP).
Known Bugs
There is one known bug:_
It is not possible to have files (!) in the directory given in DATA_BACKUP_DIRS_HOME. Only directories are allowed here. For me this is no restriction, maybe for others.
Final
I hope this script can help somebody else to create his own backup solution. I'm sure that someone can improve my script. Feel free to do that. Some parts of the code are written in a way I found out - not the best one.