4 REMOTE_DIR=/tmp/backmeupscotty/test
 
   5 ARCHIVE_KEEPNBACKUPS=30
 
   7 BACKUP_RUNEVERYNTHDAY=1
 
  10     echo $(basename $0) | tr '[:lower:]' '[:upper:]'
 
  17 function scottyerror {
 
  18     echo $(upperme): $@ >&2 
 
  21 function grepbackups {
 
  22     ssh $REMOTE_HOST "ls $REMOTE_DIR" | grep -E '[0-9]+-[0-9]+'
 
  25 function isIncomplete {
 
  26     if ( ssh $REMOTE_HOST '[ -d '$REMOTE_DIR/incomplete' ]' ); then
 
  33 function isIncompleteOrNthDay {
 
  35         [ $(( ( $(date +%s) / (60*60*24) ) % $BACKUP_RUNEVERYNTHDAY )) -eq 0 ]; 
 
  46     scottyinfo Syncing $SYNC_SRC to $REMOTE_HOST:$REMOTE_DIR @$timestamp
 
  48     if [ ! -d "$SYNC_SRC" ]; then
 
  49         scottyerror Source dir $SYNC_SRC does not exist. Not syncing!
 
  53     if [ $(ls -A "$SYNC_SRC" | wc -l) -eq 0 ]; then
 
  54         scottyerror Source dir $SYNC_SRC is empty. Not syncing!
 
  58     dir_current=$REMOTE_DIR/current
 
  59     dir_incomplete=$REMOTE_DIR/incomplete
 
  60     dir_timestamped=$REMOTE_DIR/$timestamp-$(date -d @$timestamp +%Y%m%d%H%M%S)
 
  62     if [ -z $SYNC_EXC ]; then
 
  65         rsync_exclude=$(eval echo --exclude={$SYNC_EXC} | tr -d {})
 
  68     if (ssh $REMOTE_HOST '[ ! -d '$REMOTE_DIR' ]'); then
 
  69         scottyinfo Creating destination directory $REMOTE_HOST:$REMOTE_DIR
 
  70         ssh $REMOTE_HOST "mkdir $REMOTE_DIR"
 
  74         scottyerror Continuing old incomplete backup
 
  77     scottyinfo Starting rsync
 
  79         -v -aHAX --numeric-ids --delete --delete-excluded \
 
  80         --link-dest=$dir_current \
 
  82         $SYNC_SRC/ $REMOTE_HOST:$dir_incomplete/
 
  85         scottyinfo Timestamping completed backup and linking to current backup
 
  87             "mv $dir_incomplete $dir_timestamped && rm -f $dir_current && ln -s $(basename $dir_timestamped) $dir_current"
 
  90     while [ $(grepbackups | wc -l) -gt $ARCHIVE_KEEPNBACKUPS ]; do
 
  91         oldestbackup=$(grepbackups | head -1)
 
  92         oldestbackuptstamp=$(echo $oldestbackup | cut -d'-' -f1)
 
  94         if [ $oldestbackuptstamp -lt $(( $(date +%s) - $ARCHIVE_KEEPNDAYS*60*60*24 )) ]; then
 
  95             scottyinfo Removing old backup $oldestbackup
 
  96             ssh $REMOTE_HOST rm -r "$REMOTE_DIR/$oldestbackup"
 
 103 function deleteLock {
 
 104     if ! rmdir /tmp/$(basename $0).lock; then
 
 105         scottyerror "Could not delete lockfile /tmp/$(basename $0).lock!"
 
 110     scottyinfo "Preparing for sync"
 
 113 function cleanup_abort {
 
 114     scottyinfo "No cleanup_abort function was defined."
 
 117 function _cleanup_abort {
 
 118     scottyerror "Caught exit signal! Cleaning up..."
 
 122     if [ $(jobs -p) ]; then
 
 123         scottyerror TERMinating remaining child processes...
 
 131     scottyinfo "No prepare function was defined."
 
 138 function cleanup_normal {
 
 139     scottyinfo "No cleanup_normal function was defined."
 
 142 function _cleanup_normal {
 
 146 function backmeupscotty {
 
 147     while getopts "qn:" opt; do
 
 153                 BACKUP_RUNEVERYNTHDAY=$OPTARG
 
 158     if ! isIncompleteOrNthDay; then
 
 159         scottyinfo "This is not the nth day and no incomplete backup exists."
 
 163     trap _cleanup_abort EXIT
 
 172 if ! mkdir /tmp/$(basename $0).lock; then
 
 173     scottyerror "Another instance of $(basename $0) is still running!"