Инструменты пользователя

Инструменты сайта


projects:linux:manual_backup_scripts:compress_image

Compress Image

Входит в набор rPi Seal

compress_image.sh
#!/bin/bash
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
# ==DIS/AUTOEXEC==
# ===Compress image===
# 07_compress_image.sh — архивирует .img в .gz или .zst по выбору
#
 
set -euo pipefail
 
# === Выбор формата архивации ===
echo "📦 Выберите формат архивации:"
echo "1 - gzip (.gz) — однопоточно"
echo "2 - pigz (.gz) — многопоточно (рекомендуется)"
echo "3 - zstd (.zst) — встроенный прогресс без pv"
echo "0 - Отмена"
read -rp "👉 Ваш выбор: " fmt
[[ "$fmt" == "0" || -z "$fmt" ]] && echo "❎ Отменено." && exit 0
 
case "$fmt" in
  1) ARCHIVER="gzip" EXT="gz" ; USE_PV=true ;;
  2) ARCHIVER="pigz" EXT="gz" ; USE_PV=true ;;
  3) ARCHIVER="zstd" EXT="zst" ; USE_PV=false ;;
  *) echo "❌ Неверный выбор."; exit 1 ;;
esac
 
# === Проверка зависимостей ===
# Проверка основной утилиты архивации
if ! command -v "$ARCHIVER" &>/dev/null; then
  echo "❌ Требуется утилита '$ARCHIVER'. Установить? [Y/n]"
  read -r ans
  if [[ "$ans" =~ ^[Yy]$ || -z "$ans" ]]; then
    sudo apt update && sudo apt install -y "$ARCHIVER"
  else
    echo "⏩ Пропуск: $ARCHIVER не установлен"
    exit 1
  fi
fi
 
# Проверка pv только если требуется
if [[ "$USE_PV" == true ]]; then
  if ! command -v pv &>/dev/null; then
    echo "❌ Требуется утилита 'pv'. Установить? [Y/n]"
    read -r ans
    if [[ "$ans" =~ ^[Yy]$ || -z "$ans" ]]; then
      sudo apt update && sudo apt install -y pv
    else
      echo "⏩ Пропуск: pv не установлен"
      exit 1
    fi
  fi
fi
 
# --- Выбор устройства / начало блока ---
NAS_PATH="/mnt/backup_nas"
if mountpoint -q "$NAS_PATH"; then
  mapfile -t DEVICES < <(lsblk -nrpo NAME,SIZE,MOUNTPOINT | grep -E "/dev/sd|/dev/nvme" | awk '{print $1":"$2":"$3}')
  DEVICES+=("$NAS_PATH::NAS")
else
  mapfile -t DEVICES < <(lsblk -nrpo NAME,SIZE,MOUNTPOINT | grep -E "/dev/sd|/dev/nvme" | awk '{print $1":"$2":"$3}')
fi
 
if [[ ${#DEVICES[@]} -eq 0 ]]; then
  echo "❌ Нет доступных устройств."
  exit 1
fi
 
echo "💾 Выберите диск с .img-файлами:"
i=1
for dev in "${DEVICES[@]}"; do
  IFS=":" read -r name size mnt <<< "$dev"
  label=""
  [[ "$mnt" == "NAS" ]] && label="🖧 сетевой диск"
  [[ -z "$mnt" && -z "$label" ]] && label="🔌 не примонтировано"
  echo "$i - $name $size $mnt $label"
  ((i++))
done
 
echo "0 - Отмена"
read -rp "👉 Ваш выбор: " choice
[[ "$choice" == "0" || -z "$choice" ]] && echo "❎ Отменено." && exit 0
(( choice < 1 || choice > ${#DEVICES[@]} )) && echo "❌ Неверный выбор." && exit 1
 
SEL_DEV="${DEVICES[$((choice-1))]}"
IFS=":" read -r DEV_NAME DEV_SIZE DEV_MNT <<< "$SEL_DEV"
 
TEMP_MOUNTED=false
if [[ "$DEV_NAME" == "$NAS_PATH" ]]; then
  TARGET_DIR="$NAS_PATH"
  echo "📁 Используем NAS каталог: $TARGET_DIR"
else
  MOUNTED_PATH=$(lsblk -nrpo NAME,MOUNTPOINT "$DEV_NAME" | awk '$2!="" {print $2; exit}')
  if [[ -n "$MOUNTED_PATH" ]]; then
    echo "✅ Используем: $MOUNTED_PATH"
    TARGET_DIR="$MOUNTED_PATH"
  else
    i=0
    while true; do
      MNT_PATH="/mnt/rpi_target$i"
      if ! mountpoint -q "$MNT_PATH"; then
        break
      fi
      ((i++))
    done
    sudo mkdir -p "$MNT_PATH"
    if sudo mount "$DEV_NAME" "$MNT_PATH"; then
      echo "✅ Устройство примонтировано: $MNT_PATH"
      TARGET_DIR="$MNT_PATH"
      TEMP_MOUNTED=true
    else
      echo "❌ Не удалось примонтировать."
      exit 1
    fi
  fi
fi
# --- Выбор устройства / конец блока ---
 
# === Поиск образов ===
mapfile -t IMG_LIST < <(find "$TARGET_DIR" -maxdepth 1 -type f -name "*.img")
if [[ ${#IMG_LIST[@]} -eq 0 ]]; then
  echo "❌ Не найдено .img файлов в $TARGET_DIR"
  $TEMP_MOUNTED && sudo umount "$TARGET_DIR"
  exit 1
fi
 
echo "🗂️ Найденные образы:"
i=1
for img in "${IMG_LIST[@]}"; do
  echo "$i - $img"
  ((i++))
done
 
echo "0 - Отмена"
read -rp "👉 Выберите образ для сжатия: " img_choice
[[ "$img_choice" == "0" || -z "$img_choice" ]] && echo "❎ Отменено." && $TEMP_MOUNTED && sudo umount "$TARGET_DIR" && exit 0
(( img_choice < 1 || img_choice > ${#IMG_LIST[@]} )) && echo "❌ Неверный выбор." && exit 1
 
IMGFILE="${IMG_LIST[$((img_choice-1))]}"
 
# === Сжатие ===
echo "[*] Сжимаю $IMGFILE в формат .$EXT..."
OUTFILE="$IMGFILE.$EXT"
if [[ -f "$OUTFILE" ]]; then
  read -rp "⚠️ Файл уже существует. Перезаписать? (y/N): " confirm
  [[ "$confirm" =~ ^[Yy]$ ]] || { echo "❎ Отмена."; $TEMP_MOUNTED && sudo umount "$TARGET_DIR"; exit 0; }
  rm -f "$OUTFILE"
fi
 
SIZE_ORIG=$(du -m "$IMGFILE" | cut -f1)
[[ "$SIZE_ORIG" -eq 0 ]] && echo "❌ Размер файла 0 МБ. Отмена." && exit 1
 
if [[ "$ARCHIVER" == "zstd" ]]; then
  echo "ℹ️ Используется ZSTD (без pv, с встроенным прогрессом)"
  zstd -19 -T0 "$IMGFILE" -o "$OUTFILE"
else
  echo "ℹ️ Используется ${ARCHIVER^^} — формат .gz"
  pv "$IMGFILE" | "$ARCHIVER" -9 > "$OUTFILE"
fi
 
SIZE_NEW=$(du -m "$OUTFILE" | cut -f1)
SAVED=$((SIZE_ORIG - SIZE_NEW))
PERCENT=$(awk "BEGIN {printf \"%.1f\", 100*$SAVED/$SIZE_ORIG}")
 
echo "✅ Сжатие завершено: $OUTFILE"
echo "📉 Экономия: $SAVED МБ (~$PERCENT%)"
 
$TEMP_MOUNTED && sudo umount "$TARGET_DIR"

*******

projects/linux/manual_backup_scripts/compress_image.txt · Последнее изменение: 2025/04/11 17:44 —

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC Attribution 4.0 International
CC Attribution 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki