4 REMOTE_DIR=/tmp/backmeupscotty/test
 
   5 ARCHIVE_KEEPNBACKUPS=30
 
   7 BACKUP_RUNEVERYNTHDAY=1
 
   9 _UPPERME=$(echo $(basename $0) | tr '[:lower:]' '[:upper:]')
 
  15 function scottyerror {
 
  16     echo $_UPPERME: $@ >&2 
 
  23     if [ $sshret -eq 255 ]; then
 
  24         scottyerror "SSH connection failed!"
 
  31 function grepbackups {
 
  32     ssh255 $REMOTE_HOST "ls $REMOTE_DIR" | grep -E '[0-9]+-[0-9]+'
 
  35 function isIncomplete {
 
  36     if ( ssh255 $REMOTE_HOST '[ -d '$REMOTE_DIR/incomplete' ]' ); then
 
  44     if [ $(( ( $(date +%s) / (60*60*24) ) % $BACKUP_RUNEVERYNTHDAY )) -eq 0 ]; 
 
  52 function latestTooOld {
 
  53     for oldbackup in $(grepbackups); do
 
  54         tstamp=$(echo $oldbackup | cut -d'-' -f1)
 
  56         if [ $(( $(date +%s) - $tstamp )) -lt \
 
  57             $(( ($BACKUP_RUNEVERYNTHDAY*24+12)*60*60 )) ]
 
  69     scottyinfo "Syncing $SYNC_SRC to $REMOTE_HOST:$REMOTE_DIR @$timestamp."
 
  71     if [ ! -d "$SYNC_SRC" ]; then
 
  72         scottyerror "Source dir $SYNC_SRC does not exist. Not syncing!"
 
  76     if [ $(ls -A "$SYNC_SRC" | wc -l) -eq 0 ]; then
 
  77         scottyerror "Source dir $SYNC_SRC is empty. Not syncing!"
 
  81     dir_current=$REMOTE_DIR/current
 
  82     dir_incomplete=$REMOTE_DIR/incomplete
 
  83     dir_timestamped=$REMOTE_DIR/$timestamp-$(date -d @$timestamp +%Y%m%d%H%M%S)
 
  85     if [ -z $SYNC_EXC ]; then
 
  88         rsync_exclude=$(eval echo --exclude={$SYNC_EXC} | tr -d {})
 
  91     if (ssh255 $REMOTE_HOST '[ ! -d '$REMOTE_DIR' ]'); then
 
  92         scottyinfo "Creating destination directory $REMOTE_HOST:$REMOTE_DIR."
 
  93         ssh255 $REMOTE_HOST "mkdir $REMOTE_DIR"
 
  97         scottyerror "Continuing old incomplete backup."
 
 100     scottyinfo "Starting rsync."
 
 102         -v -aHAX --numeric-ids --delete --delete-excluded \
 
 103         --link-dest=$dir_current \
 
 105         $SYNC_SRC/ $REMOTE_HOST:$dir_incomplete/
 
 107     if [ $? -eq 0 ]; then
 
 108         scottyinfo "Timestamping completed backup and linking to current backup."
 
 109         ssh255 $REMOTE_HOST \
 
 110             "mv $dir_incomplete $dir_timestamped && rm -f $dir_current && ln -s $(basename $dir_timestamped) $dir_current"
 
 113     while [ $(grepbackups | wc -l) -gt $ARCHIVE_KEEPNBACKUPS ]; do
 
 114         oldestbackup=$(grepbackups | head -1)
 
 115         oldestbackuptstamp=$(echo $oldestbackup | cut -d'-' -f1)
 
 117         if [ $oldestbackuptstamp -lt $(( $(date +%s) - $ARCHIVE_KEEPNDAYS*60*60*24 )) ]; then
 
 118             scottyinfo "Removing old backup $oldestbackup."
 
 119             ssh255 $REMOTE_HOST rm -r "$REMOTE_DIR/$oldestbackup"
 
 126 function deleteLock {
 
 127     if ! rmdir /var/lock/$(basename $0); then
 
 128         scottyerror "Could not delete lockfile /tmp/$(basename $0).lock!"
 
 132 function cleanup_abort {
 
 133     scottyerror "Caught exit signal! Cleaning up."
 
 137     if [ $(jobs -p) ]; then
 
 138         scottyerror "TERMinating remaining child processes."
 
 148     scottyinfo "No cleanup function was defined."
 
 152     scottyinfo "No prepare function was defined."
 
 155 function cleanup_normal {
 
 162 Usage: $(basename $0) [OPTION]...
 
 165   -q   Only output errors
 
 166   -n   Run only on nth day
 
 167   -h   Print out this help
 
 171 function backmeupscotty {
 
 172     while getopts "qn:h" opt; do
 
 178                 BACKUP_RUNEVERYNTHDAY=$OPTARG
 
 187     ssh255 $REMOTE_HOST exit
 
 189     if latestTooOld; then
 
 190         scottyerror "The latest backup is too old."
 
 192         scottyinfo "This is the nth day."
 
 194         scottyinfo "No backup has to be done. Exiting."
 
 198     scottyinfo "Performing backup."
 
 200     trap cleanup_abort EXIT
 
 205     trap cleanup_normal EXIT
 
 210 if ! mkdir /var/lock/$(basename $0); then
 
 211     scottyerror "Another instance of $(basename $0) is still running!"