5 REMOTE_DIR=/tmp/backmeupscotty/test
6 ARCHIVE_KEEPNBACKUPS=30
8 BACKUP_RUNEVERYNTHDAY=1
16 date +'[%y-%m-%d|%H:%M:%S]'
24 if [ $_ERROR_ENCOUNTERED -eq 0 ]; then
31 function scottyerror {
33 if [ $_ERROR_ENCOUNTERED -eq 0 ]; then
35 scottyline "Going into verbose mode after error encounter." >&2
40 ssh -l $REMOTE_USER $@
43 if [ $sshret -eq 255 ]; then
44 scottyerror "SSH connection failed!"
51 function grepbackups {
52 ssh255 $REMOTE_HOST "ls $REMOTE_DIR" | grep -E '[0-9]+-[0-9]+'
55 function isIncomplete {
56 if ( ssh255 $REMOTE_HOST '[ -d '$REMOTE_DIR/incomplete' ]' ); then
64 if [ $(( ( $(date +%s) / (60*60*24) ) % $BACKUP_RUNEVERYNTHDAY )) -eq 0 ];
72 function latestTooOld {
73 for oldbackup in $(grepbackups); do
74 tstamp=$(echo $oldbackup | cut -d'-' -f1)
76 if [ $(( $(date +%s) - $tstamp )) -lt $(( ($BACKUP_RUNEVERYNTHDAY*24+12)*60*60 )) ]
88 scottyinfo "Syncing $SYNC_SRC to $REMOTE_HOST:$REMOTE_DIR @$timestamp."
90 if [ ! -d "$SYNC_SRC" ]; then
91 scottyerror "Source dir $SYNC_SRC does not exist. Not syncing!"
95 if [ $(ls -A "$SYNC_SRC" | wc -l) -eq 0 ]; then
96 scottyerror "Source dir $SYNC_SRC is empty. Not syncing!"
100 dir_current=$REMOTE_DIR/current
101 dir_incomplete=$REMOTE_DIR/incomplete
102 dir_timestamped=$REMOTE_DIR/$timestamp-$(date -d @$timestamp +%Y%m%d%H%M%S)
104 if [ -z $SYNC_EXC ]; then
107 rsync_exclude=$(eval echo --exclude={$SYNC_EXC} | tr -d {})
110 if [ $FAKE_SUPER -eq 1 ]; then
111 rsync_fake_super="--rsync-path=\"rsync --fake-super\""
116 if (ssh255 $REMOTE_HOST '[ ! -d '$REMOTE_DIR' ]'); then
117 scottyinfo "Creating destination directory $REMOTE_HOST:$REMOTE_DIR."
118 ssh255 $REMOTE_HOST "mkdir $REMOTE_DIR"
121 if isIncomplete; then
122 scottyerror "Continuing old incomplete backup."
125 scottyinfo "Starting rsync."
126 rsync -e "ssh -l $REMOTE_USER" --bwlimit=$BWLIMIT \
127 -v -aHAX --numeric-ids --delete --delete-excluded \
128 --link-dest=$dir_current \
129 $rsync_exclude $rsync_fake_super \
130 $SYNC_SRC/ $REMOTE_HOST:$dir_incomplete/
132 if [ $? -eq 0 ]; then
133 scottyinfo "Timestamping completed backup and linking to current backup."
134 ssh255 $REMOTE_HOST \
135 "mv $dir_incomplete $dir_timestamped && rm -f $dir_current && \
136 ln -s $(basename $dir_timestamped) $dir_current"
138 scottyerror "Rsync failed."
141 while [ $(grepbackups | wc -l) -gt $ARCHIVE_KEEPNBACKUPS ]; do
142 oldestbackup=$(grepbackups | head -1)
143 oldestbackuptstamp=$(echo $oldestbackup | cut -d'-' -f1)
145 if [ $oldestbackuptstamp -lt $(( $(date +%s) - $ARCHIVE_KEEPNDAYS*60*60*24 )) ]; then
146 scottyinfo "Removing old backup $oldestbackup."
147 ssh255 $REMOTE_HOST rm -r "$REMOTE_DIR/$oldestbackup"
154 function deleteLock {
155 if ! rmdir /var/lock/$(basename $0); then
156 scottyerror "Could not delete lockfile /tmp/$(basename $0).lock!"
160 function cleanup_abort {
161 scottyerror "Caught exit signal! Cleaning up."
165 if [ $(jobs -p) ]; then
166 scottyerror "TERMinating remaining child processes."
176 scottyinfo "No cleanup function was defined."
180 scottyinfo "No prepare function was defined."
183 function cleanup_normal {
190 Usage: $(basename $0) [OPTION]...
193 -q Only output errors
194 -n Run only on nth day
196 -l List existing backups
197 -h Print out this help
201 function exclusiveLock {
202 if ! mkdir /var/lock/$(basename $0); then
203 scottyerror "Another instance of $(basename $0) is still running!"
210 function backmeupscotty {
211 while getopts "qn:flh" opt; do
217 BACKUP_RUNEVERYNTHDAY=$OPTARG
232 ssh255 $REMOTE_HOST exit
234 if [ $LIST_BACKUPS ]; then
235 for backup in $(grepbackups); do
243 if [ $BACKUP_FORCE -eq 1 ]; then
244 scottyinfo "Backup was enforced."
245 elif latestTooOld; then
246 scottyerror "The latest backup is too old."
248 scottyinfo "This is the nth day."
250 scottyinfo "No backup has to be done. Exiting."
254 scottyinfo "Performing backup."
256 trap cleanup_abort EXIT
261 trap cleanup_normal EXIT