projects:linux:backups
Различия
Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия | ||
projects:linux:backups [2025/03/28 12:53] – [Таблица] | projects:linux:backups [2025/03/30 00:17] (текущий) – [Основной скрипт] | ||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | ===== Создание резервной копии SD карты ===== | + | ====== Создание резервной копии SD карты |
+ | |||
+ | =====Основной скрипт===== | ||
++++Скрипт создания резервной копии SD карты на USB носитель| | ++++Скрипт создания резервной копии SD карты на USB носитель| | ||
- | <file bash backup_sd.sh> | + | <code bash sd_backup.sh> |
#!/bin/bash | #!/bin/bash | ||
+ | export LANG=C.UTF-8 | ||
# ==AUTOEXEC== | # ==AUTOEXEC== | ||
- | # === Резервирование | + | # === SD BackUp |
- | # * Резервирование SD карты | + | # Резервное копирование SD карты |
- | # * и перезапуском после окончания | + | # Расширенный скрипт резервного копирования SD |
- | # * в локальной сети wireguard останавливается и | + | # с автоустановкой |
- | # * запускается резервное копирование | + | # |
- | # * копия после создания сжимается (или нет, по выбору), | + | |
- | # * комментарий запрошенный при запуске скрипта | + | |
- | export LANG=en_US.UTF-8 | + | VERSION="1.2" |
- | export LC_ALL=en_US.UTF-8 | + | SCRIPT_NAME=" |
- | # === Самозащита: запускаем теневую копию === | + | if [[ " |
- | if [[ "$0" == "$BASH_SOURCE" | + | echo "📘 Использование: $SCRIPT_NAME [опции]" |
- | | + | echo |
- | | + | echo " |
- | | + | echo " |
- | echo "🚨 Запуск временной копии: $TMP_CLONE" | + | |
- | | + | echo " |
+ | echo " | ||
+ | | ||
+ | echo " | ||
+ | | ||
+ | | ||
+ | echo " | ||
+ | echo " | ||
+ | echo " | ||
+ | echo " | ||
+ | echo " | ||
+ | | ||
+ | echo " | ||
+ | exit 0 | ||
fi | fi | ||
- | # Путь к папке для бэкапов на SSD | + | if [[ "$1" == "--version" |
- | BACKUP_DIR="/ | + | echo "$SCRIPT_NAME v$VERSION" |
- | # Устройство SD-карты (проверьте имя командой lsblk) | + | |
- | SD_CARD="/ | + | |
- | # Текущая дата и время для формирования имени файла | + | |
- | DATE=$(date +" | + | |
- | + | ||
- | # Меню выбора действия | + | |
- | echo "=== Меню ===" | + | |
- | echo "1. Создать резервную копию (сжать gzip)" | + | |
- | echo "2. Создать резервную копию (без сжатия)" | + | |
- | echo "0. Выход" | + | |
- | echo " | + | |
- | read CHOICE | + | |
- | + | ||
- | if [ "$CHOICE" == "0" ]; then | + | |
- | echo "🚪 Выход из скрипта." | + | |
exit 0 | exit 0 | ||
fi | fi | ||
- | if [ " | + | # Определение директории логов |
- | | + | if [[ -d /mnt/usb ]]; then |
- | | + | LOG_DIR="/ |
+ | elif [[ -d /tmp ]]; then | ||
+ | | ||
+ | else | ||
+ | | ||
fi | fi | ||
+ | mkdir -p " | ||
- | # Запрос комментария у пользователя | + | log() { |
- | echo "Введите комментарий к резервной копии | + | echo "[$(date +'%F %T')] $1" | tee -a " |
- | read COMMENT | + | } |
- | if [ -z "$COMMENT" ]; then | + | # ... остальной скрипт будет дополнен ниже |
- | | + | |
+ | # Параметры и аргументы | ||
+ | CONFIG_FILE=" | ||
+ | USE_CONFIG=false | ||
+ | REQUIRED_CMDS=(dd gzip xz zstd losetup parted e2fsck resize2fs tune2fs kpartx mount sha256sum) | ||
+ | INSTALL=false | ||
+ | |||
+ | NON_INTERACTIVE=false | ||
+ | KEEP_DAYS=0 | ||
+ | KEEP_COUNT=0 | ||
+ | TEMPLATE="" | ||
+ | KEEP_IMG=false | ||
+ | source_img="" | ||
+ | |||
+ | for arg in " | ||
+ | case $arg in | ||
+ | --comment=*) comment=" | ||
+ | --compress=*) compression=" | ||
+ | --shrink) shrink=true ;; | ||
+ | --no-shrink) shrink=false ;; | ||
+ | --sha256) sha256=true ;; | ||
+ | --no-sha256) sha256=false ;; | ||
+ | --device=*) sd_card=" | ||
+ | --keep-days=*) KEEP_DAYS=" | ||
+ | --keep-count=*) KEEP_COUNT=" | ||
+ | --log=*) LOG_FILE=" | ||
+ | --template=*) TEMPLATE=" | ||
+ | --keep-img) KEEP_IMG=true ;; | ||
+ | --source=*) source_img=" | ||
+ | -n|--non-interactive) NON_INTERACTIVE=true ;; | ||
+ | -y|--auto-install) INSTALL=true ;; | ||
+ | esac | ||
+ | done | ||
+ | |||
+ | if $INSTALL; then | ||
+ | MISSING=() | ||
+ | for cmd in " | ||
+ | if ! command | ||
+ | done | ||
+ | if [[ ${# | ||
+ | | ||
+ | sudo apt-get update -y && sudo apt-get install -y " | ||
+ | else | ||
+ | log "✅ Все зависимости уже установлены." | ||
+ | fi | ||
fi | fi | ||
- | # Функция транслитерации кириллицы | + | if [[ -f " |
- | transliterate() { | + | |
- | | + | if [[ "$use_config" |
- | -e ' | + | log "📝 Используем параметры из конфиг-файла $CONFIG_FILE" |
- | -e ' | + | |
- | -e ' | + | fi |
- | -e 's/п/p/g' -e 's/р/r/g' -e ' | + | fi |
- | | + | |
- | -e ' | + | |
- | -e ' | + | |
- | -e ' | + | |
- | -e ' | + | |
- | -e ' | + | |
- | -e ' | + | |
- | -e ' | + | |
- | -e ' | + | |
- | -e ' | + | |
- | -e ' | + | |
- | -e ' | + | |
- | } | + | |
- | # Очистка комментария перед транслитерацией для имени файла | + | if [[ " |
- | CLEAN_COMMENT=$(echo | + | backup_dir="/ |
- | SAFE_COMMENT=$(transliterate " | + | temp_dir="/ |
+ | sd_card="/ | ||
+ | comment=" | ||
+ | | ||
+ | | ||
+ | sha256=true | ||
+ | fi | ||
- | # Формирование имени | + | if [[ " |
- | EXT="img" | + | echo "=== Меню |
- | if [ " | + | echo "1. Снимок - dd + gzip" |
- | EXT="img.gz" | + | echo "2. Снимок - dd без сжатия" |
+ | echo "3. Снимок - dd + shrink" | ||
+ | echo "4. Снимок - dd + shrink + gzip" | ||
+ | echo "5. Снимок - dd + shrink + xz" | ||
+ | echo "6. Уменьшить существующий образ" | ||
+ | echo "7. Уменьшить и сжать существующий образ (gzip)" | ||
+ | echo "8. Уменьшить и сжать существующий образ (zstd)" | ||
+ | | ||
+ | read -p " | ||
+ | case " | ||
+ | 1) compression=" | ||
+ | 2) compression="none"; | ||
+ | 3) compression="none"; shrink=true;; | ||
+ | 4) compression=" | ||
+ | 5) compression=" | ||
+ | 6) read -p " | ||
+ | 7) read -p " | ||
+ | 8) read -p " | ||
+ | 0) echo "🚪 Выход"; | ||
+ | *) echo "❌ Неверный выбор"; | ||
+ | esac | ||
+ | [[ -z " | ||
fi | fi | ||
- | BACKUP_FILE=" | ||
- | # Проверка, | + | mkdir -p " |
- | if [ ! -d "$BACKUP_DIR" ]; then | + | |
- | | + | if [[ -z "$source_img" |
- | exit 1 | + | |
+ | sudo systemctl stop systemd-journald.socket | ||
+ | sudo systemctl stop systemd-journald.service | ||
fi | fi | ||
- | # Определение IP клиента и проверка на WireGuard-подсеть | + | date_now=$(date +"%Y-%m-%d_%H-%M-%S" |
- | CLIENT_IP=$(who am i | awk '{print $5}' | grep -oE '[0-9.]+') | + | comment_safe=$(echo " |
- | if [[ "$CLIENT_IP" | + | basename=${TEMPLATE: |
- | | + | basename=$(echo " |
- | | + | img_file=" |
+ | |||
+ | if [[ -n "$source_img" ]]; then | ||
+ | | ||
+ | | ||
else | else | ||
- | echo "⏸️ Останавливаем WireGuard (wg-quick@wg0)..." | + | log "💾 Создаём образ SD: $img_file" |
- | sudo systemctl stop wg-quick@wg0 | + | sudo dd if=" |
- | WG_STOPPED=1 | + | |
fi | fi | ||
- | # Сброс буферов перед резервным копированием | + | if [[ ! -f " |
- | echo "💾 Сброс буферов | + | |
- | sync | + | |
- | # Получение | + | if [[ " |
- | SD_SIZE=$(sudo blockdev | + | log "🔧 Уменьшение |
- | HUMAN_SIZE=$(numfmt --to=iec $SD_SIZE) | + | [[ ! -x ./ |
- | echo "📦 Ожидаемый общий размер: | + | |
- | ESTIMATED_MIN=$(numfmt --to=iec $((SD_SIZE * 30 / 100))) | + | |
- | ESTIMATED_MAX=$(numfmt | + | sudo ./ |
- | echo "🧮 После сжатия ожидаемый размер архива: | + | fi |
- | # Резервное копирование через dd с отображением прогресса | + | final_file=" |
- | echo "📋 Копирование с помощью dd..." | + | |
- | if [ "$CHOICE" == "1" ]; then | + | if [[ "$compression" |
- | | + | log "📦 Сжатие gzip..." |
- | else | + | |
- | | + | final_file=" |
+ | elif [[ "$compression" == "xz" | ||
+ | | ||
+ | xz -T0 -z " | ||
+ | final_file="${final_file}.xz" | ||
+ | elif [[ " | ||
+ | log "📦 Сжатие zstd..." | ||
+ | | ||
+ | final_file="${final_file}.zst" | ||
fi | fi | ||
- | echo "✅ Чтение завершено." | + | [[ $KEEP_DAYS -gt 0 ]] && find "$backup_dir" |
+ | [[ $KEEP_COUNT -gt 0 ]] && ls -tp " | ||
- | # Запуск WireGuard после резервного копирования (если мы его останавливали) | + | if [[ "$sha256" == "true" ]]; then |
- | if [[ "$WG_STOPPED" == "1" ]]; then | + | |
- | | + | |
- | sudo systemctl start wg-quick@wg0 | + | echo " |
fi | fi | ||
- | # Сохранение комментария в лог-файле | + | [[ -n " |
- | echo -e "$DATE - $COMMENT" | iconv -f utf-8 -t utf-8 -c | tee -a "$BACKUP_DIR/ | + | |
- | # Вывод размера итогового файла | + | final_dest=" |
- | FILE_SIZE=$(du -h "$BACKUP_FILE" | + | log "📁 Перемещаем |
- | echo "📦 Размер резервной | + | mv " |
+ | [[ " | ||
- | # Создание контрольной суммы SHA256 | + | log "🎉 Готово: $final_dest" |
- | SHA_FILE=" | + | |
- | echo "🔐 Создаём контрольную сумму SHA256..." | + | |
- | sha256sum " | + | |
- | echo "🎉 Резервное копирование | + | if [[ -z "$source_img" |
- | echo "✅ Резервная копия: $BACKUP_FILE" | + | log "🔔 Включаем обратно системное логирование" |
- | echo "🔐 Контрольная сумма сохранена: $SHA_FILE" | + | sudo systemctl start systemd-journald.socket |
+ | sudo systemctl start systemd-journald.service | ||
+ | fi | ||
+ | |||
+ | exit 0 | ||
- | </file>++++ | + | </code>++++ |
===== MarkDown ===== | ===== MarkDown ===== | ||
Строка 184: | Строка 258: | ||
--- | --- | ||
- | ## 🧪 Примеры запуска | + | ===== 🧪 Примеры запуска |
- | ### 📦 Съём и сжатие: | + | 📦 Съём и сжатие: |
- | ```bash | + | |
+ | < | ||
./ | ./ | ||
- | ``` | + | </ |
- | ### 🗃️ Обработка существующего `.img`, shrink + gzip: | + | 🗃️ Обработка существующего `.img`, shrink + gzip: |
- | ```bash | + | < |
./ | ./ | ||
- | ``` | + | </ |
- | ### ♻️ Просто сжать `.img`, без shrink: | + | ♻️ Просто сжать `.img`, без shrink: |
- | ```bash | + | < |
./ | ./ | ||
- | ``` | + | </ |
--- | --- | ||
- | ## 📝 Замечания | + | 📝 Замечания |
- | - Поддерживает | + | |
- | - Все параметры можно комбинировать. | + | - Все параметры можно комбинировать. |
- | - Подходит для cron, systemd, ручных задач и GUI-обёрток. | + | - Подходит для cron, systemd, ручных задач и GUI-обёрток. |
projects/linux/backups.1743155598.txt.gz · Последнее изменение: 2025/03/28 12:53 —