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 
 
  25     if [ $sshret -eq 255 ]; then
 
  26         scottyerror "SSH connection failed!"
 
  33 function grepbackups {
 
  34     ssh255 $REMOTE_HOST "ls $REMOTE_DIR" | grep -E '[0-9]+-[0-9]+'
 
  37 function isIncomplete {
 
  38     if ( ssh255 $REMOTE_HOST '[ -d '$REMOTE_DIR/incomplete' ]' ); then
 
  46     if [ $(( ( $(date +%s) / (60*60*24) ) % $BACKUP_RUNEVERYNTHDAY )) -eq 0 ]; 
 
  54 function latestTooOld {
 
  55     for oldbackup in $(grepbackups); do
 
  56         tstamp=$(echo $oldbackup | cut -d'-' -f1)
 
  58         if [ $(( $(date +%s) - $tstamp )) -lt \
 
  59             $(( ($BACKUP_RUNEVERYNTHDAY*24+12)*60*60 )) ]
 
  71     scottyinfo "Syncing $SYNC_SRC to $REMOTE_HOST:$REMOTE_DIR @$timestamp."
 
  73     if [ ! -d "$SYNC_SRC" ]; then
 
  74         scottyerror "Source dir $SYNC_SRC does not exist. Not syncing!"
 
  78     if [ $(ls -A "$SYNC_SRC" | wc -l) -eq 0 ]; then
 
  79         scottyerror "Source dir $SYNC_SRC is empty. Not syncing!"
 
  83     dir_current=$REMOTE_DIR/current
 
  84     dir_incomplete=$REMOTE_DIR/incomplete
 
  85     dir_timestamped=$REMOTE_DIR/$timestamp-$(date -d @$timestamp +%Y%m%d%H%M%S)
 
  87     if [ -z $SYNC_EXC ]; then
 
  90         rsync_exclude=$(eval echo --exclude={$SYNC_EXC} | tr -d {})
 
  93     if (ssh255 $REMOTE_HOST '[ ! -d '$REMOTE_DIR' ]'); then
 
  94         scottyinfo "Creating destination directory $REMOTE_HOST:$REMOTE_DIR."
 
  95         ssh255 $REMOTE_HOST "mkdir $REMOTE_DIR"
 
  99         scottyerror "Continuing old incomplete backup."
 
 102     scottyinfo "Starting rsync."
 
 104         -v -aHAX --numeric-ids --delete --delete-excluded \
 
 105         --link-dest=$dir_current \
 
 107         $SYNC_SRC/ $REMOTE_HOST:$dir_incomplete/
 
 109     if [ $? -eq 0 ]; then
 
 110         scottyinfo "Timestamping completed backup and linking to current backup."
 
 111         ssh255 $REMOTE_HOST \
 
 112             "mv $dir_incomplete $dir_timestamped && rm -f $dir_current && ln -s $(basename $dir_timestamped) $dir_current"
 
 115     while [ $(grepbackups | wc -l) -gt $ARCHIVE_KEEPNBACKUPS ]; do
 
 116         oldestbackup=$(grepbackups | head -1)
 
 117         oldestbackuptstamp=$(echo $oldestbackup | cut -d'-' -f1)
 
 119         if [ $oldestbackuptstamp -lt $(( $(date +%s) - $ARCHIVE_KEEPNDAYS*60*60*24 )) ]; then
 
 120             scottyinfo "Removing old backup $oldestbackup."
 
 121             ssh255 $REMOTE_HOST rm -r "$REMOTE_DIR/$oldestbackup"
 
 128 function deleteLock {
 
 129     if ! rmdir /var/lock/$(basename $0); then
 
 130         scottyerror "Could not delete lockfile /tmp/$(basename $0).lock!"
 
 134 function cleanup_abort {
 
 135     scottyerror "Caught exit signal! Cleaning up."
 
 139     if [ $(jobs -p) ]; then
 
 140         scottyerror "TERMinating remaining child processes."
 
 150     scottyinfo "No cleanup function was defined."
 
 154     scottyinfo "No prepare function was defined."
 
 157 function cleanup_normal {
 
 164 Usage: $(basename $0) [OPTION]...
 
 167   -q   Only output errors
 
 168   -n   Run only on nth day
 
 169   -h   Print out this help
 
 173 function backmeupscotty {
 
 174     while getopts "qn:h" opt; do
 
 180                 BACKUP_RUNEVERYNTHDAY=$OPTARG
 
 189     ssh255 $REMOTE_HOST exit
 
 191     if latestTooOld; then
 
 192         scottyerror "The latest backup is too old."
 
 194         scottyinfo "This is the nth day."
 
 196         scottyinfo "No backup has to be done. Exiting."
 
 200     scottyinfo "Performing backup."
 
 202     trap cleanup_abort EXIT
 
 207     trap cleanup_normal EXIT
 
 212 if ! mkdir /var/lock/$(basename $0); then
 
 213     scottyerror "Another instance of $(basename $0) is still running!"