#!/bin/sh ## rolling-backup.sh, v0.1 ## Copyright (C) 2001, 2002 Gary Benson ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. # Script to perform backups, 'rolling' in the sense that a number of # older copies are kept as well. Invoke (from cron or similar) with # the name of a directory full of config files as the only argument. # # Config file directives: # FILE (mandatory) -- name of the file to save the backup as # CMD (mandatory), # ARGS (optional) -- "$CMD $ARGS" is the command to write the data to # be backed up to stdout. # # As an example, the entry I use to back up my diary on advogato.org is: # # --- cut here --- # # rolling-backup config file to backup my diary on Advogato. # # FILE="$HOME/backups/advogato/diary.xml" # CMD="wget" # ARGS="-q -O - http://www.advogato.org/person/gary/diary.xml" # --- stop cutting --- ########################################################################### # Check the arguments if [ $# != 1 ]; then echo 1>&2 "usage: $0 configdir" exit 1 fi # Process all files in the supplied directory for CONFIG in $1/*[^~] do # Fill in the defaults, then source and check the configfile unset FILE CMD ARGS . $CONFIG || exit 1 if [ "x$FILE" = "x" ]; then echo 1>&2 "mandatory option `FILE' not set" exit 1 fi if [ "x$CMD" = "x" ]; then echo 1>&2 "mandatory option `CMD' not set" exit 1 fi # Split $FILE pushd `dirname $FILE` > /dev/null || exit 1 FILE=`basename $FILE` # Dump the data. TMP=`mktemp $FILE.XXXXXXXX` || exit 1 $CMD $ARGS > $TMP || exit 1 if [ ! -f $FILE ] then # This is the first backup ever: rename $TMP mv $TMP $FILE else # Only replace files if they have changed diff -q $TMP $FILE > /dev/null case $? in 2) exit 1 ;; 0) # No change rm -f $TMP ;; 1) # Changed test -f $FILE.4 && rm -f $FILE.4 for i in 3 2 1 do test -f $FILE.$i && mv $FILE.$i $FILE.`expr $i + 1` done mv $FILE $FILE.1 mv $TMP $FILE ;; *) echo 1>&2 "diff returned $?" exit 1 esac fi popd >> /dev/null || exit 1 done exit 0