pankovea-patch-1 #1
165
zfs_send.zsh
165
zfs_send.zsh
@ -1,5 +1,16 @@
|
||||
#!/bin/zsh
|
||||
|
||||
#TODO list
|
||||
# 1. Скрипт не определяет, что нужно остановиться
|
||||
# 2. Возникают ошибки:
|
||||
# sending main_pool/3D_Design@manual-20250327 (99%: 21.9G/21.9G) 25.6M/s date: invalid date ‘@0.’
|
||||
# date: invalid date ‘@954.’
|
||||
# sending main_pool/3D_Design@manual-20250327 (100%: 21.9G/21.9G) 25.6M/s date: invalid date ‘@-1.’
|
||||
# date: invalid date ‘@954.’
|
||||
# 3. Нужно автоматически определить, если копирование уже запущено то предложить остановить и вывести процесс резервирования
|
||||
# смотреть нужно сразу на всей системе. Не будем запускать несколько параллельных резервирований.
|
||||
|
||||
|
||||
backup_server="192.168.0.162" # Сервер для резервирования
|
||||
backup_user="root" # Пользователь на сервере
|
||||
inc_snapshot="manual-$(date +%Y%m%d)" # Новый создаваемый снисмок
|
||||
@ -123,10 +134,14 @@ identitiesOnly yes
|
||||
|
||||
|
||||
|
||||
|
||||
# !
|
||||
# Если нужно вывести только прогресс, то пропускаем все этапы подготовки и резервирования
|
||||
if [[ $progress_only = false ]]; then
|
||||
|
||||
|
||||
|
||||
|
||||
# Завершение запущенного процесса резервирования
|
||||
if [[ $stop = true ]]; then
|
||||
pids=$(ps -t $(tty | sed 's|/dev/||') -o pid,args | grep -e zfs_send.zsh -e "zfs send" | grep -v -- '--stop') # Список PIDs с командой запуска
|
||||
@ -369,6 +384,7 @@ if [[ $work = "y" || $work = "Y" ]]; then
|
||||
(( n_tasks++ ))
|
||||
echo "$key \t ${last_loc_snaps[$loc_ds]} \t -> \t${work_datasets[$loc_ds]}" >> "$LOGFILE"
|
||||
done
|
||||
echo $n_tasks > /dev/shm/backup_n_tasks
|
||||
|
||||
echo_log
|
||||
echo_log "--- Резервирую данные ---"
|
||||
@ -391,74 +407,167 @@ if [[ $work = "y" || $work = "Y" ]]; then
|
||||
done & # Запустить резервирование в фоне
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# !
|
||||
# Конец блока условия progress_only
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
# Вывод прогресса
|
||||
# Это отдельный блок программы, который не имеет прямого доступа к переменным процесса в фоне.
|
||||
# Обмен переменными проивится ерез временный файл
|
||||
if [[ $progress == true ]]; then
|
||||
echo ""
|
||||
|
||||
pids=$(ps -t $(tty | sed 's|/dev/||') -o pid,args | grep -e zfs_send.zsh -e "zfs send" ) # Список PIDs с командой запуска
|
||||
pids=$(ps -t $(tty | sed 's|/dev/||') -o pid,args | grep -e zfs_send.zsh -e "zfs send" | grep -v -- 'grep' | grep -v -- 'progress-only' ) # Список PIDs с командой запуска
|
||||
|
||||
if [[ $pids = "" ]]; then
|
||||
echo "Нет запущенного процесса резервирования в этом терминале."
|
||||
read "srch?Икать во всех процессах системы? (y/N) "
|
||||
if [[ $srch = y ]]; then
|
||||
pids=$(ps -o pid,args | grep -e zfs_send.zsh -e "zfs send" )
|
||||
pids=$(ps a -o pid,args | grep -e zfs_send.zsh -e "zfs send" | grep -v -- 'grep' | grep -v -- 'progress-only' )
|
||||
fi
|
||||
fi
|
||||
|
||||
echo $pids
|
||||
# Выводить прогресс запрашивая список запущенных процессов
|
||||
if [[ $pids = "" ]]; then
|
||||
echo "Нет запущенного процесса резервирования"
|
||||
else
|
||||
echo ""
|
||||
# инициализируем переменнные
|
||||
TS0=$(< /dev/shm/backup_time_start)
|
||||
TS1=$(< /dev/shm/backup_time_circle)
|
||||
|
||||
last_percent=0
|
||||
time_changed_percent_value=$(date +%s)
|
||||
last_volume=0
|
||||
last_volume_time=$TS1
|
||||
speed=0
|
||||
reset_interval=10 # интревал сбрасывания скорости до нуля, в случае если нет именений
|
||||
last_update_time=$TS1 # Время последнего обновления
|
||||
|
||||
time_changed_percent_value=$TS1
|
||||
|
||||
n_tasks=$(< /dev/shm/backup_n_tasks)
|
||||
i_task=$(< /dev/shm/backup_i_task)
|
||||
while [[ $i_task != $n_tasks ]]; do # выводим статус пока не завершены все задачи
|
||||
progress=$(ps -u | grep "sending" | grep -v "grep" | sed -r "s/(.*) zfs: (.*)/\2/")
|
||||
percent=$(echo $progress | cut -d "(" -f2 | cut -d "%" -f1 )
|
||||
|
||||
# Извлекаем объем и процент
|
||||
progress_part=$(echo "$progress" | grep -oP '\(\K.*(?=\))') # Извлекаем только часть в скобках
|
||||
|
||||
if [[ -n $progress_part ]]; then
|
||||
# Разбиваем часть на компоненты
|
||||
# Процент определим по объёму
|
||||
# percent=$(echo "$progress_part" | awk -F': |/' '{print $1}' | tr -d '%')
|
||||
current_volume_str=$(echo "$progress_part" | awk -F': |/' '{print $2}')
|
||||
total_volume_str=$(echo "$progress_part" | awk -F': |/' '{print $3}')
|
||||
|
||||
# Определяем единицу для интервала сброса
|
||||
unit=${current_volume_str: -1}
|
||||
case $unit in
|
||||
G) reset_interval=100;;
|
||||
M) reset_interval=10;;
|
||||
*) reset_interval=5;;
|
||||
esac
|
||||
|
||||
# Преобразуем в байты
|
||||
current=$(echo "$current_volume_str" | awk '{sub(/[^0-9.]/,""); print $1}')
|
||||
case $unit in
|
||||
G) current_volume=$(( current * 1073741824 )) ;;
|
||||
M) current_volume=$(( current * 1048576 )) ;;
|
||||
K) current_volume=$(( current * 1024 )) ;;
|
||||
*) current_volume=0 ;;
|
||||
esac
|
||||
|
||||
total=$(echo "$total_volume_str" | awk '{sub(/[^0-9.]/,""); print $1}')
|
||||
case $unit in
|
||||
G) total_volume=$(( total * 1073741824 )) ;;
|
||||
M) total_volume=$(( total * 1048576 )) ;;
|
||||
K) total_volume=$(( total * 1024 )) ;;
|
||||
*) total_volume=0 ;;
|
||||
esac
|
||||
|
||||
percent=$(( current_volume * 100 / total_volume ))
|
||||
else
|
||||
percent=0
|
||||
current_volume=0
|
||||
fi
|
||||
|
||||
# Вычисляем скорость
|
||||
now=$(date +%s)
|
||||
|
||||
# Если объем изменился
|
||||
elapsed_from_vol_change=$((now - last_volume_time))
|
||||
if [[ $current_volume -ne $last_volume && elapsed_from_vol_change -ne 0 ]]; then
|
||||
speed=$(awk "BEGIN { printf \"%.1f\", ($current_volume - $last_volume) / $elapsed_from_vol_change }")
|
||||
last_volume=$current_volume
|
||||
last_volume_time=$now
|
||||
last_update_time=$now # Обновляем время последнего изменения
|
||||
else
|
||||
# Если объем не изменился, проверяем время с последнего обновления
|
||||
time_since_update=$((now - last_update_time))
|
||||
if (( time_since_update >= reset_interval )); then
|
||||
speed=0 # Обнуляем скорость, если нет изменений в течение интервала
|
||||
last_update_time=$now # Обновляем время
|
||||
fi
|
||||
fi
|
||||
|
||||
# Конвертируем скорость в человекочитаемый формат
|
||||
if (( speed > 1073741824 )); then
|
||||
speed_human=$(awk "BEGIN { printf \"%.1fG\", $speed / 1073741824 }")
|
||||
elif (( speed > 1048576 )); then
|
||||
speed_human=$(awk "BEGIN { printf \"%.1fM\", $speed / 1048576 }")
|
||||
elif (( speed > 1024 )); then
|
||||
speed_human=$(awk "BEGIN { printf \"%.1fK\", $speed / 1024 }")
|
||||
else
|
||||
speed_human="${speed}B"
|
||||
fi
|
||||
|
||||
|
||||
# Начинаем вывод
|
||||
echo -n "\033[2K\r$progress $speed_human/s "
|
||||
|
||||
if (( percent > 0 )); then
|
||||
now=$(date +%s)
|
||||
if (( percent != last_percent )); then
|
||||
time_changed_percent_value=$now
|
||||
last_percent=$percent
|
||||
TS1=$(< /dev/shm/backup_time_circle)
|
||||
elapsed=$(( $(date +%s) - TS1 ))
|
||||
elapsed_total=$(( $(date +%s) - TS1 ))
|
||||
fi
|
||||
time_part_of_percent=$(( now - time_changed_percent_value )) # Время с последнего изменения процента
|
||||
estimated_total=$(( 100 / percent * elapsed )) # Всего времени на задачу
|
||||
estimated_remain=$(( estimated_total - elapsed - time_part_of_percent )) # Осталось времени на задачу
|
||||
estimated_total=$(( 100 / percent * elapsed_total )) # Всего времени на задачу
|
||||
estimated_remain=$(( estimated_total - elapsed_total - time_part_of_percent )) # Осталось времени на задачу
|
||||
if (( estimated_remain >= 86400 )) || (( estimated_total >= 86400 )); then # Если осталось более чем сутки, то отобразить дни
|
||||
estimated_remain_days=$(( estimated_remain / 86400 )); estimated_remain_time=$(( estimated_remain % 86400 ))
|
||||
estimated_total_days=$(( estimated_total / 86400 )); estimated_total_time=$(( estimated_total % 86400 ))
|
||||
echo -n "\033[2K\r$progress $estimated_remain_days д. $(date -d@$estimated_remain_time -u '+%H:%M.%S') ост. / $estimated_total_days д. $(date -d@$estimated_total_time -u '+%H:%M.%S') "
|
||||
echo -n " $estimated_remain_days д. $(date -d@$estimated_remain_time -u '+%H:%M.%S') ост. / $estimated_total_days д. $(date -d@$estimated_total_time -u '+%H:%M.%S') "
|
||||
else
|
||||
echo -n "\033[2K\r$progress $(date -d@$estimated_remain -u '+%H:%M.%S') ост. / $(date -d@$estimated_total -u '+%H:%M.%S') "
|
||||
echo -n " $(date -d@$estimated_remain -u '+%H:%M.%S') ост. / $(date -d@$estimated_total -u '+%H:%M.%S') "
|
||||
fi
|
||||
sleep 1
|
||||
else
|
||||
echo -ne "\033[2K\r$progress "
|
||||
sleep 1
|
||||
for ((i = 1; i < 3 ; i++)); do echo -n "."; sleep 1; done
|
||||
for ((i = 1; i < 4 ; i++)); do echo -n "."; sleep 1; done
|
||||
fi
|
||||
i_task=$(< /dev/shm/backup_i_task)
|
||||
|
||||
sleep 1
|
||||
|
||||
done
|
||||
|
||||
if [[ -f /dev/shm/backup_time_start ]]; then
|
||||
TS0=$(< /dev/shm/backup_time_start)
|
||||
echo_log "\n--- Все завершено за $(date -d@$(( $(date +%s) - $TS0 )) -u '+%H:%M.%S') ---\n"
|
||||
else
|
||||
echo_log "\n--- Все задания завершены ---\n"
|
||||
fi
|
||||
|
||||
# Удалить временные файлы состояний, если они существуют
|
||||
[ -f /dev/shm/backup_i_task ] && rm /dev/shm/backup_i_task
|
||||
[ -f /dev/shm//dev/shm/backup_time_start ] && rm /dev/shm/backup_time_start
|
||||
[ -f /dev/shm//dev/shm/backup_time_circle ] && rm /dev/shm/backup_time_circle
|
||||
|
||||
fi
|
||||
|
||||
if [[ -f /dev/shm/backup_time_start ]]; then
|
||||
TS0=$(< /dev/shm/backup_time_start)
|
||||
echo_log "\n--- Все завершено за $(date -d@$(( $(date +%s) - $TS0 )) -u '+%H:%M.%S') ---\n"
|
||||
else
|
||||
echo_log "\n--- Все задания завершены ---\n"
|
||||
fi
|
||||
|
||||
# Удалить временные файлы состояний, если они существуют
|
||||
[ -f /dev/shm/backup_i_task ] && rm /dev/shm/backup_i_task
|
||||
[ -f /dev/shm//dev/shm/backup_time_start ] && rm /dev/shm/backup_time_start
|
||||
[ -f /dev/shm//dev/shm/backup_time_circle ] && rm /dev/shm/backup_time_circle
|
||||
|
||||
|
||||
fi
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user