Skip to content

Instantly share code, notes, and snippets.

@rssws
Created March 8, 2021 21:29
Show Gist options
  • Save rssws/6f9ae04e08a71bb06951f63313030661 to your computer and use it in GitHub Desktop.
Save rssws/6f9ae04e08a71bb06951f63313030661 to your computer and use it in GitHub Desktop.
Backup script using rsync and tar. Automatically delete old backups when space not sufficient.
###################
# settings
backup_dir=<path to the backup directory> # e.g. /root/backup
remote_server=<example.com> # ip address or server name set in ssh config, same as using the ssh or scp
server_name=<server_name> # a tag for the log purpose and will be the backup folder name
###################
startTime=$(date +%s)
# define color
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# define header
INFO="${BLUE}[INFO]${NC}"
WARNING="${YELLOW}[WARNING]${NC}"
SUCCESS="${GREEN}[SUCCESS]${NC}"
ERROR="${RED}[ERROR]${NC}"
# initialize
printf "${GREEN}"
printf "================================== \n"
printf "BACKUP SCRIPT \n"
printf " \n"
printf "Server: $server_name\n"
printf "Date: $(date)\n"
printf "================================== \n"
printf "${NC}\n"
if [ -d "$backup_dir/$server_name" ]; then
cd $backup_dir/$server_name
else
print "${ERROR} Backup path ${backup_dir}/${server_name} not found, abort!\n"
exit 1
fi
# tar & compress backup from 2 days ago
tmpDate=$(date -d '-2 day' '+%Y%m%d')
if [ -d "$tmpDate" ]; then
printf "${INFO} Compressing the backup ${tmpDate} into tar.gz ...\n"
find ${tmpDate} -type s -print > ./${tmpDate}.sockets-to-exclude
tar cfz ${tmpDate}.tar.gz -X ./${tmpDate}.sockets-to-exclude $tmpDate
rm -rf $tmpDate
rm -rf ${tmpDate}.sockets-to-exclude
fi
curDate=$(date +'%Y%m%d')
# check disk size
diskTotal=$(df -lh | grep /dev/simfs | awk '{print $2}')
diskAvail=$(df -lh | grep /dev/simfs | awk '{print $4}')
diskUsed=$(df -lh | grep /dev/simfs | awk '{print $3}')
diskAvailQuation=$(df -lh | grep /dev/simfs | awk '{print $5}')
printf "${INFO} Disk: %6s %6s %6s %6s\n" Size Avail Used Use%
printf " %6s %6s %6s %6s\n" $diskTotal $diskAvail $diskUsed $diskAvailQuation
# delete old backups if disAvailable is smaller than 50G
diskAvailByte=$(df | grep /dev/simfs | awk '{print $4}')
while [ ${diskAvailByte} -lt 52428800 ]
do
oldestBackup=$(ls . | head -1)
printf "${WARNING} Disk remaining size is smaller than 50G\n" >&2
printf "${INFO} oldest backup: ${oldestBackup}.tar.gz\n"
# check if the system still doesn't have enough space to backup
remainingBackupNumber=$(ls . | wc -l)
if [ ${remainingBackupNumber:0} -le 1 ]; then
printf "${ERROR} There is still no sufficient space! Leaving the latest backup untouched and aborting ...\n" >&2
exit 1
fi
printf "${INFO} Deleting the oldest backup: ${oldestBackup}.tar.gz ... \n"
rm -rf ${oldestBackup}.tar.gz
wait
# check again whether directory is deleted
if [ -d "${oldestBackup}.tar.gz" ] ; then
printf "${ERROR} Failed to delete the oldest backup\n" >&2
exit 1
else
printf "${SUCCESS} Successfully deleted the oldest backup: ${oldestBackup}.tar.gz\n"
diskAvailByte=$(df | grep /dev/simfs | awk '{print $4}')
fi
done
# create backup dir if not exists
if [ ! -d "$curDate" ]; then
mkdir $curDate
fi
printf "${INFO} Backup directory: $backup_dir/$server_name/$curDate\n"
printf "${INFO} Executing rsync ...\n"
rsync -ah $remote_server:/ $curDate --progress \
--exclude=/dev/* \
--exclude=/home/*/.gvfs \
--exclude=/home/*/.mozilla/firefox/*/Cache \
--exclude=/home/*/.cache/chromium \
--exclude=/home/*/.thumbnails \
--exclude=/media/* \
--exclude=/mnt/* \
--exclude=/proc/* \
--exclude=/sys/* \
--exclude=/tmp/* \
--exclude=/etc/fstab \
--exclude=/var/run/* \
--exclude=/var/lock/* \
--exclude=/lib/modules/*/volatile/.mounted \
--exclude=/var/cache/apt/archives/* \
--exclude=/var/lib/docker/* \
--exclude=/root/swapfile > /dev/null # comment "> /dev/null out" if you want to see standard output
retCode=$?
# echo $retCode
if [ ${retCode} -ne 0 ]; then
printf "${ERROR} rsync exited with errors!\n" >&2
exit 1
else
printf "${SUCCESS} Backup finished!\n"
fi
endTime=$(date +%s)
runtime=$(echo "$endTime - $startTime" | bc -l)
printf "${INFO} Total time used: $(date -d@$runtime -u +%H:%M:%S)\n"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment