#!/bin/zsh # --------- Собираем данные ---------- backup_server="192.168.0.162" srcpool="main_pool/" inc_snapshot="manual-$(date +%Y%m%d)" # Словарь, содержащий списки резервируемых датасетов declare -A datasets # ["${srcpool}3D_Design"]="NOD/Backup/3D_Design" # ["${srcpool}Backups"]="NOD/Backup/Backups" # ["${srcpool}Documents"]="NOD/Backup/Documents" # ["${srcpool}Family"]="NOD/Backup/Family" # ["${srcpool}FTP_users"]="NOD/Backup/FTP_users" datasets=( ["${srcpool}Media"]="NOD/Backup/Media" ["${srcpool}NOD/GenShtab"]="NOD/GenShtab" ["${srcpool}NOD/MinDiz"]="NOD/MinDiz" ["${srcpool}NOD/nod34"]="NOD/nod34" ["${srcpool}NOD/nod34_secret"]="NOD/nod34_secret" ["${srcpool}PhotoWork"]="NOD/Backup/PhotoWork" ) # Словарь со списком последких снапшотов для датасетов declare -A last_local_snaps declare -A last_backup_snaps pre_snapshots=() for ds in ${(k)datasets}; do tmp="$(zfs list -r -t snapshot -H -o name ${srcpool::-1} | grep ${ds} | grep "manual" | egrep -o '@.+' | tail -n1)" tmp=${tmp:1} if [ "$tmp" = "$inc_snapshot" ]; then read "del_snapshot?Датасет $ds уже имеет последний снимок $inc_snapshot. Удалить? (y/N)" if [ "$del_snapshot" = "y" ]; then zfs destroy "${ds}@${tmp}" tmp="$(zfs list -r -t snapshot -H -o name ${srcpool::-1} | grep ${ds} | grep "manual" | egrep -o '@.+' | tail -n1)" pre_snapshots[$ds]="${tmp:1}" else # Если не удалять, то просто исключить из резервирования unset "datasets[$ds]" fi else pre_snapshots[$ds]=$tmp fi done # --------- Запрашиваем подтверждение пользователя ---------- echo echo "Резервирование на $backup_server" echo "Список резервируемых датасетов:" for key in ${(k)datasets}; do echo "$key \t ${pre_snapshots[$key]} \t -> \t${datasets[$key]}" done echo echo "Инкрементный снимок:\t$inc_snapshot" read "work?Утвердите данные. Приступаем? (y/N) " # --------- Резервирование ---------- if [ "$work" = "y" ] then TS0=$(date +%s) LOGFILE="log_${inc_snapshot}_backup.txt" echo "Результат работы записываю в файл $LOGFILE" echo "Список резервируемых датасетов:" >> $LOGFILE for key in ${(k)datasets}; do echo "$key \t ${pre_snapshots[$key]} \t -> \t${datasets[$key]}" >> $LOGFILE done echo exec 6>&1 # Saves stdout exec >> >(tee $LOGFILE) # stdout replaced with file echo "------------------------\nСоздаю снимки @${inc_snapshot}\n" TS1=$(date +%s) for ds in ${(k)datasets}; do echo " * ${ds}"; zfs snapshot ${ds}@${inc_snapshot}; done TS2=$(date +%s) echo "Готово за: $(date -d@$(($TS2-$TS1)) -u +'%H:%M.%S')" echo "------------------------\nРезервирую данные\n" for ds in ${(k)datasets}; do TS1=$(date +%s) echo " * Start sending ${ds} at $(date +'%Y.%m.%d %H:%M.%S')" zfs send -V -i ${ds}@${pre_snapshots[$ds]} ${ds}@${inc_snapshot} | ssh "root@${backup_server}" zfs receive ${datasets[$ds]}@${inc_snapshot} TS2=$(date +%s) echo "Закончил ${ds} за: $(date -d@$(($TS2-$TS1)) -u +%H:%M:%S)" done & exec 1>&6 6>&- while pgrep -u $USER zfs >/dev/null; do PROGR=$(ps -u | grep "send" | grep -v "grep" | sed -r "s/(.*) zfs: (.*)/\2/") echo -ne "$PROGR\033[0K\r" # echo -ne "$(ps -u | grep "send" | grep -v "grep" | sed -r "s/(.*) zfs: (.*)/\2/")\033[0K\r" sleep 60 done echo -e exec >> >(tee $LOGFILE) echo "------------------------\nВсе завершено за $(date -d@$(($TS2-$TS0)) -u +%H:%M.%S)" exec 1>&6 6>&- # Restore stdout and close file descriptor #6. fi