#!/bin/bash #full full() { echo "[full]" #mark running touch ${dst_dir}/running #max_backups must >= 2 [ $max_backups -lt 2 ] && max_backups=2 #get old_backups old_backups=$(ls ${dst_dir}/full | wc -l) echo "!$old_backups!" #delete old backups to max_backups-1 while [ ${old_backups} -ge ${max_backups} ] do oldest_dir=$(ls ${dst_dir}/full | sort -n | head -n 1) #find oldest dir by name rm -r ${dst_dir}/full/${oldest_dir} rm -r ${dst_dir}/diff/${oldest_dir} echo "remove ${oldest_dir}" old_backups=$((old_backups-1)) done #create new backup dir mkdir ${dst_dir}/full/$(date +"%F") mkdir ${dst_dir}/diff/$(date +"%F") rsync -av $src_dir ${dst_dir}/full/$(date +"%F")/ rm ${dst_dir}/running } #diff diff() { echo "[diff]" #mark running touch ${dst_dir}/running #max_backups must >= 2 [ $max_backups -lt 2 ] && max_backups=2 #find newest full dir by name newest_full=$(ls ${dst_dir}/full | sort -rn | head -n 1) #get old_backups old_backups=$(ls ${dst_dir}/diff/${newest_full} | wc -l) echo "!$old_backups!" #delete old backups to max_backups-1 while [ ${old_backups} -ge ${max_backups} ] do oldest_dir=$(ls ${dst_dir}/diff/${newest_full} | sort -n | head -n 1) #find oldest dir by name rm -r ${dst_dir}/diff/${newest_full}/${oldest_dir} echo "remove ${oldest_dir}" old_backups=$((old_backups-1)) done #create new backup dir mkdir ${dst_dir}/diff/${newest_full}/$(date +"%F_T%H") rsync -av $src_dir ${dst_dir}/diff/${newest_full}/$(date +"%F_T%H")/ --link-dest=../../../full/${newest_full}/ rm ${dst_dir}/running } #init init() { echo "[init]" #check src_dir readable [ ! -r $src_dir ] && echo "src_dir cannot read" #check dst_dir writeable if [ ! -w $dst_dir ]; then echo "dst_dir cannot write" else #create needed dir mkdir ${dst_dir}/full mkdir ${dst_dir}/diff echo "init ok" fi } #------------main-------------# #assign arg to var src_dir=$3 dst_dir=$4 mode=$1 max_backups=$2 #check init only if [[ $src_dir == "" ]] || [[ $dst_dir == "" ]] ; then echo no src_dir or dst_dir input exit 1 fi #set src_dir end without / if [[ $src_dir == */ ]]; then src_dir=${src_dir%?} fi #set dst_dir end without / if [[ $dst_dir == */ ]]; then dst_dir=${dst_dir%?} fi #input debug #echo "$mode $src_dir $dst_dir" #check if other processing running if [ -f ${dst_dir}/running ]; then echo "other processing running" exit 2 fi #mode if [ $mode == "full" ]; then full elif [ $mode == "diff" ]; then diff elif [ $mode == "init" ]; then init else echo "no mode select" #exit 4 fi #debug #echo $(ls ${dst_dir}/full | sort -n | head -n 1)