pankovea-patch-1 #1

Merged
pankovea merged 11 commits from pankovea-patch-1 into main 2025-07-14 15:22:41 +00:00
Showing only changes of commit f55223926f - Show all commits

View File

@ -1,5 +1,16 @@
#!/bin/zsh #!/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_server="192.168.0.162" # Сервер для резервирования
backup_user="root" # Пользователь на сервере backup_user="root" # Пользователь на сервере
inc_snapshot="manual-$(date +%Y%m%d)" # Новый создаваемый снисмок inc_snapshot="manual-$(date +%Y%m%d)" # Новый создаваемый снисмок
@ -123,10 +134,14 @@ identitiesOnly yes
# !
# Если нужно вывести только прогресс, то пропускаем все этапы подготовки и резервирования # Если нужно вывести только прогресс, то пропускаем все этапы подготовки и резервирования
if [[ $progress_only = false ]]; then if [[ $progress_only = false ]]; then
# Завершение запущенного процесса резервирования # Завершение запущенного процесса резервирования
if [[ $stop = true ]]; 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 с командой запуска 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++ )) (( n_tasks++ ))
echo "$key \t ${last_loc_snaps[$loc_ds]} \t -> \t${work_datasets[$loc_ds]}" >> "$LOGFILE" echo "$key \t ${last_loc_snaps[$loc_ds]} \t -> \t${work_datasets[$loc_ds]}" >> "$LOGFILE"
done done
echo $n_tasks > /dev/shm/backup_n_tasks
echo_log echo_log
echo_log "--- Резервирую данные ---" echo_log "--- Резервирую данные ---"
@ -391,74 +407,167 @@ if [[ $work = "y" || $work = "Y" ]]; then
done & # Запустить резервирование в фоне done & # Запустить резервирование в фоне
fi fi
# !
# Конец блока условия progress_only # Конец блока условия progress_only
fi fi
# Вывод прогресса # Вывод прогресса
# Это отдельный блок программы, который не имеет прямого доступа к переменным процесса в фоне.
# Обмен переменными проивится ерез временный файл
if [[ $progress == true ]]; then if [[ $progress == true ]]; then
echo "" 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 if [[ $pids = "" ]]; then
echo "Нет запущенного процесса резервирования в этом терминале." echo "Нет запущенного процесса резервирования в этом терминале."
read "srch?Икать во всех процессах системы? (y/N) " read "srch?Икать во всех процессах системы? (y/N) "
if [[ $srch = y ]]; then 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
fi fi
echo $pids
# Выводить прогресс запрашивая список запущенных процессов # Выводить прогресс запрашивая список запущенных процессов
if [[ $pids = "" ]]; then if [[ $pids = "" ]]; then
echo "Нет запущенного процесса резервирования" echo "Нет запущенного процесса резервирования"
else else
echo "" echo ""
# инициализируем переменнные
TS0=$(< /dev/shm/backup_time_start)
TS1=$(< /dev/shm/backup_time_circle)
last_percent=0 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 # выводим статус пока не завершены все задачи while [[ $i_task != $n_tasks ]]; do # выводим статус пока не завершены все задачи
progress=$(ps -u | grep "sending" | grep -v "grep" | sed -r "s/(.*) zfs: (.*)/\2/") 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 if (( percent > 0 )); then
now=$(date +%s) now=$(date +%s)
if (( percent != last_percent )); then if (( percent != last_percent )); then
time_changed_percent_value=$now time_changed_percent_value=$now
last_percent=$percent last_percent=$percent
TS1=$(< /dev/shm/backup_time_circle) TS1=$(< /dev/shm/backup_time_circle)
elapsed=$(( $(date +%s) - TS1 )) elapsed_total=$(( $(date +%s) - TS1 ))
fi fi
time_part_of_percent=$(( now - time_changed_percent_value )) # Время с последнего изменения процента time_part_of_percent=$(( now - time_changed_percent_value )) # Время с последнего изменения процента
estimated_total=$(( 100 / percent * elapsed )) # Всего времени на задачу estimated_total=$(( 100 / percent * elapsed_total )) # Всего времени на задачу
estimated_remain=$(( estimated_total - elapsed - time_part_of_percent )) # Осталось времени на задачу estimated_remain=$(( estimated_total - elapsed_total - time_part_of_percent )) # Осталось времени на задачу
if (( estimated_remain >= 86400 )) || (( estimated_total >= 86400 )); then # Если осталось более чем сутки, то отобразить дни if (( estimated_remain >= 86400 )) || (( estimated_total >= 86400 )); then # Если осталось более чем сутки, то отобразить дни
estimated_remain_days=$(( estimated_remain / 86400 )); estimated_remain_time=$(( estimated_remain % 86400 )) estimated_remain_days=$(( estimated_remain / 86400 )); estimated_remain_time=$(( estimated_remain % 86400 ))
estimated_total_days=$(( estimated_total / 86400 )); estimated_total_time=$(( estimated_total % 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 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 fi
sleep 1
else else
echo -ne "\033[2K\r$progress " for ((i = 1; i < 4 ; i++)); do echo -n "."; sleep 1; done
sleep 1
for ((i = 1; i < 3 ; i++)); do echo -n "."; sleep 1; done
fi fi
i_task=$(< /dev/shm/backup_i_task)
sleep 1
done 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 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 fi