Skip to content

Instantly share code, notes, and snippets.

@euikook
Last active February 19, 2018 07:57
Show Gist options
  • Save euikook/71f1fb969f0144c61e99bf3da947f33c to your computer and use it in GitHub Desktop.
Save euikook/71f1fb969f0144c61e99bf3da947f33c to your computer and use it in GitHub Desktop.
Backup using rsync+ssh
#!/usr/bin/env bash
#Title : gbackup
#Description : Backup script using rsync+ssh
#Author : E.K. KIM (euikook@gmail.com)
#Date : 2018-02-19
#Version : 1.0
#Usage : gbackup [-i] [-d DAYS] [-h REMOTE-HOST] [-e SSH-OPTS] <SRC-DIR> <DST-DIR>
#Notes : None
# m h dom mon dow command
# 00 04 * * * ~/bin/gbackup -h s01 -e ssh /home /home/backup/s01/home
# 00 05 * * * ~/bin/gbackup -h s02 -e ssh /home /home/backup/s02/home
# 00 06 * * * ~/bin/gbackup -h s03 -e ssh /home /home/backup/s03/home
# VARIABLES
DURATIONS=0 # Number of days which keep old backup.
EXCLUDES=".gbackup.excludes"
# EXECUTABLES
SSH=/usr/bin/ssh
SCP=/usr/bin/scp
FIND=/usr/bin/find
DATE=/bin/date
MKDIR=/bin/mkdir
TOUCH=/bin/touch
SLINK="ln -s"
ECHO=/bin/echo
ECHOERR=">&2 $ECHO"
DELETE=/bin/rm
DELETEF="/bin/rm -f"
DELETERF="rm -rf"
RSYNC=/usr/bin/rsync
REMOTERSYNC="/usr/bin/sudo /usr/bin/rsync"
TODAY=`$DATE "+%Y-%m-%d"`
INCBKUP=0
while [ $# -gt 0 ]; do
case "$1" in
-h | --host) RM_HOST=$2; shift;;
-e | --ssh ) RM_OPTS=$2; shift;;
-i | --incremental ) INCBKUP=1; ;;
-d | --delete-old-backup ) DURATIONS=$2; shift;;
-*) $ECHOERR >&2 "usage $0 [-h HOST] [-i] [-e SSH_OPTION] <SRC DIR> <DST DIR>"
exit 1;;
*) break;; # terminate while loop
esac
shift;
done
SRC_DIR=$1
DST_DIR=$2
[[ $DURATIONS =~ ^-?[0-9]+$ ]] || {
$ECHOERR "'$DURATIONS' is not integer"
exit 0
}
if [ $RM_HOST = "" ]; then
SSH_OPTS=""
BKUP_SRC=$SRC_DIR
else
SSH_OPTS="-e \"$RM_OPTS\""
BKUP_SRC="$($ECHO "$RM_HOST:$SRC_DIR/" | sed 's/ /\\ /g')"
fi
BKUP_DST=$DST_DIR
[ -d "$BKUP_DST" ] || {
$ECHOERR "No such file or directory: '$BKUP_DST'"
exit 1;
}
cd "$BKUP_DST"
RSYNC_OPTS="-apvz \
$SSH_OPTS \
--numeric-ids"
if [ "$INCBKUP" -eq "1" ]; then
LASTEST=$BKUP_DST/lastest
UUID=`uuid -v 4`
CURRENT="$BKUP_DST/$TODAY/$UUID"
if [ -L "$LASTEST" ]; then
LINKDEST="--link-dest=\"$LASTEST\""
fi
RSYNC_OPTS+=" $LINKDEST"
LOG_DIR="$BKUP_DST/$TODAY"
BKUP_LOG=$LOG_DIR/$UUID.log
else
CURRENT="$BKUP_DST"
RSYNC_OPTS+=" --delete \
--delete-excluded"
BKUP_NAME=`basename "$BKUP_DST"`
LOG_DIR="$BKUP_DST/../Log"
BKUP_LOG="$LOG_DIR/$BKUP_NAME-$NOW.log"
fi
RSYNC_EXCL_OPTS="--delete --include=\"$EXCLUDES\" --exclude=\"*\""
RSYNC_EXCL="$RSYNC $RSYNC_OPTS \
$SYNC_EXCL_OPTS \
\"$BKUP_SRC\" \
\"$BKUP_DST\""
# Sync excludes file first.
eval $RSYNC_EXCL 2>&1 > /dev/null
[ -f "$DST_DIR/$EXCLUDES" ] && {
RSYNC_OPTS+=" --exclude-from \"$DST_DIR/$EXCLUDES\""
}
[ -d "$LOG_DIR" ] || {
$MKDIR -p "$LOG_DIR"
}
$DATE > "$BKUP_LOG"
RSYNC_BKUP="$RSYNC $RSYNC_OPTS \
\"$BKUP_SRC\" \
\"$CURRENT\""
$ECHO $RSYNC_BKUP >> "$BKUP_LOG"
eval $RSYNC_BKUP 2>&1 >> "$BKUP_LOG" || {
$ECHOERR "Can't backup from \"$BKUP_SRC\"."
$ECHOERR "Please see more details \"$BKUP_LOG\"."
exit -1
}
$TOUCH "$CURRENT"
if [ "$INCBKUP" -eq "1" ]; then
$DELETEF "$LASTEST"
$SLINK `realpath --relative-to="$BKUP_DST" "$CURRENT"` "$LASTEST"
$TOUCH "$LASTEST"
# REMOVE OLD BACKUPS
[ "$DURATIONS" -gt "0" ] && {
LIST=$( $FIND "$DST_DIR" -maxdepth 1 -type d -mtime +$DURATIONS )
for FILE in $LIST; do
$ECHO "DELETE OLD THAN $DURATIONS days: $FILE"
# UNCOMMENT BELOW LINE CAREFULLY!!
$DELETERF "$FILE"
done
}
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment