При выполнении долгих скриптов (например, обработки данных или резервного копирования) важно предусмотреть механизм безопасного прерывания с возможностью продолжения с того места, где процесс остановился. Сегодня про то, как можно организовать такую систему в Bash с использованием файлов-снапшотов.
Файл-снапшот хранит состояние выполнения скрипта. При запуске скрипт проверяет наличие этого файла, чтобы понять, нужно ли продолжить работу или начать заново.
💡 Реализация
Предположим, у нас есть список файлов для обработки. Скрипт будет:
Чтить файл-снапшот, чтобы определить, с какого места продолжить.
Обрабатывать файлы по одному.
Обновлять прогресс в snap-файле.
#!/bin/bash
# Имя файла-снапшота
SNAPSHOT_FILE="progress.snapshot"
# Список задач (например, файлы для обработки)
FILES=("file1.txt" "file2.txt" "file3.txt" "file4.txt" "file5.txt")
# Чтение текущего прогресса из снапшота
CURRENT_INDEX=0
if [[ -f $SNAPSHOT_FILE ]]; then
CURRENT_INDEX=$(<"$SNAPSHOT_FILE")
echo "Прогресс найден: начнем с файла ${FILES[$CURRENT_INDEX]}"
else
echo "Снапшот не найден: начнем сначала"
fi
# Обработка файлов
for ((i=CURRENT_INDEX; i<${#FILES[@]}; i++)); do
echo "Обрабатываю ${FILES[$i]}..."
# Имитация долгой обработки
sleep 2
echo "Файл ${FILES[$i]} обработан!"
# Обновление прогресса в файле-снапшоте
echo $((i + 1)) > "$SNAPSHOT_FILE"
done
# Удаление снапшота после завершения работы
rm -f "$SNAPSHOT_FILE"
echo "Все файлы обработаны, прогресс очищен!"
Примеры вывода
Первый запуск:
Снапшот не найден: начнем сначала
Обрабатываю file1.txt...
Файл file1.txt обработан!
Обрабатываю file2.txt...
Файл file2.txt обработан!
...
Если прервать выполнение, то прогресс сохранится в progress.snapshot.
Повторный запуск:
Прогресс найден: начнем с файла file3.txt
Обрабатываю file3.txt...
Файл file3.txt обработан!
...
🔎 Обработка ошибок
Чтобы обеспечить надежность:
Проверяйте, существует ли файл перед обработкой.
Используйте команды trap для удаления временных файлов при непредвиденных ошибках.
Логируйте результаты обработки.
trap 'rm -f $SNAPSHOT_FILE; echo "Ошибка! Прогресс сохранен.";' SIGINT SIGTERM
🔗 Расширенная версия: поддержка нескольких процессов
Для обработки в несколько потоков можно использовать отдельные снапшоты для каждой задачи. Например:
for file in "${FILES[@]}"; do
{
if [[ ! -f "${file}.done" ]]; then
echo "Обрабатываю $file..."
sleep 2 # Имитация обработки
echo "Файл $file обработан!"
touch "${file}.done"
fi
} &
done
wait
Файлы-снапшоты - простой, но важный инструмент для повышения надежности скриптов. Они позволяют безопасно прерывать и продолжать выполнение, экономя ваше время.
BashTex 📱 #bash #utils