4 REMOTE_DIR=/tmp/backmeupscotty/test
5 ARCHIVE_KEEPNBACKUPS=30
7 BACKUP_RUNEVERYNTHDAY=1
14 date +'[%y-%m-%d|%H:%M:%S]'
22 if [ $_ERROR_ENCOUNTERED -eq 0 ]; then
29 function scottyerror {
31 if [ $_ERROR_ENCOUNTERED -eq 0 ]; then
33 scottyline "Going into verbose mode after error encounter." >&2
41 if [ $sshret -eq 255 ]; then
42 scottyerror "SSH connection failed!"
49 function grepbackups {
50 ssh255 $REMOTE_HOST "ls $REMOTE_DIR" | grep -E '[0-9]+-[0-9]+'
53 function isIncomplete {
54 if ( ssh255 $REMOTE_HOST '[ -d '$REMOTE_DIR/incomplete' ]' ); then
62 if [ $(( ( $(date +%s) / (60*60*24) ) % $BACKUP_RUNEVERYNTHDAY )) -eq 0 ];
70 function latestTooOld {
71 for oldbackup in $(grepbackups); do
72 tstamp=$(echo $oldbackup | cut -d'-' -f1)
74 if [ $(( $(date +%s) - $tstamp )) -lt $(( ($BACKUP_RUNEVERYNTHDAY*24+12)*60*60 )) ]
86 scottyinfo "Syncing $SYNC_SRC to $REMOTE_HOST:$REMOTE_DIR @$timestamp."
88 if [ ! -d "$SYNC_SRC" ]; then
89 scottyerror "Source dir $SYNC_SRC does not exist. Not syncing!"
93 if [ $(ls -A "$SYNC_SRC" | wc -l) -eq 0 ]; then
94 scottyerror "Source dir $SYNC_SRC is empty. Not syncing!"
98 dir_current=$REMOTE_DIR/current
99 dir_incomplete=$REMOTE_DIR/incomplete
100 dir_timestamped=$REMOTE_DIR/$timestamp-$(date -d @$timestamp +%Y%m%d%H%M%S)
102 if [ -z $SYNC_EXC ]; then
105 rsync_exclude=$(eval echo --exclude={$SYNC_EXC} | tr -d {})
108 if (ssh255 $REMOTE_HOST '[ ! -d '$REMOTE_DIR' ]'); then
109 scottyinfo "Creating destination directory $REMOTE_HOST:$REMOTE_DIR."
110 ssh255 $REMOTE_HOST "mkdir $REMOTE_DIR"
113 if isIncomplete; then
114 scottyerror "Continuing old incomplete backup."
117 scottyinfo "Starting rsync."
118 rsync -e ssh --bwlimit=$BWLIMIT \
119 -v -aHAX --numeric-ids --delete --delete-excluded \
120 --link-dest=$dir_current \
122 $SYNC_SRC/ $REMOTE_HOST:$dir_incomplete/
124 if [ $? -eq 0 ]; then
125 scottyinfo "Timestamping completed backup and linking to current backup."
126 ssh255 $REMOTE_HOST \
127 "mv $dir_incomplete $dir_timestamped && rm -f $dir_current && \
128 ln -s $(basename $dir_timestamped) $dir_current"
130 scottyerror "Rsync failed."
133 while [ $(grepbackups | wc -l) -gt $ARCHIVE_KEEPNBACKUPS ]; do
134 oldestbackup=$(grepbackups | head -1)
135 oldestbackuptstamp=$(echo $oldestbackup | cut -d'-' -f1)
137 if [ $oldestbackuptstamp -lt $(( $(date +%s) - $ARCHIVE_KEEPNDAYS*60*60*24 )) ]; then
138 scottyinfo "Removing old backup $oldestbackup."
139 ssh255 $REMOTE_HOST rm -r "$REMOTE_DIR/$oldestbackup"
146 function deleteLock {
147 if ! rmdir /var/lock/$(basename $0); then
148 scottyerror "Could not delete lockfile /tmp/$(basename $0).lock!"
152 function cleanup_abort {
153 scottyerror "Caught exit signal! Cleaning up."
157 if [ $(jobs -p) ]; then
158 scottyerror "TERMinating remaining child processes."
168 scottyinfo "No cleanup function was defined."
172 scottyinfo "No prepare function was defined."
175 function cleanup_normal {
182 Usage: $(basename $0) [OPTION]...
185 -q Only output errors
186 -n Run only on nth day
188 -l List existing backups
189 -h Print out this help
193 function exclusiveLock {
194 if ! mkdir /var/lock/$(basename $0); then
195 scottyerror "Another instance of $(basename $0) is still running!"
202 function backmeupscotty {
203 while getopts "qn:flh" opt; do
209 BACKUP_RUNEVERYNTHDAY=$OPTARG
224 ssh255 $REMOTE_HOST exit
226 if [ $LIST_BACKUPS ]; then
227 for backup in $(grepbackups); do
235 if [ $BACKUP_FORCE -eq 1 ]; then
236 scottyinfo "Backup was enforced."
237 elif latestTooOld; then
238 scottyerror "The latest backup is too old."
240 scottyinfo "This is the nth day."
242 scottyinfo "No backup has to be done. Exiting."
246 scottyinfo "Performing backup."
248 trap cleanup_abort EXIT
253 trap cleanup_normal EXIT