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

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


projects:linux:manual_backup_scripts:shrink_img

Это старая версия документа!


Shrink Image

shrink_image.sh
#!/bin/bash
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
# ==DIS/AUTOEXEC==
# ===Shrink image===
# shrink_image.sh — применить pishrink к образу Raspberry Pi, с возможностью двойного прохода и сохранением оригинала
#
 
set -euo pipefail
 
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SHRINK_SCRIPT="$SCRIPT_DIR/pishrink.sh"
 
# --- Выбор устройства / начало блока ---
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/.img.gz:"
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" -o -name "*.img.gz" \))
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))]}"
 
# 🗜 Распаковка .gz
if [[ "$IMGFILE" =~ \.gz$ ]]; then
  echo "🗜 Найден архив. Распаковать .gz в .img?"
  read -rp "(y/N): " unpack_confirm
  if [[ "$unpack_confirm" =~ ^[Yy]$ ]]; then
    gunzip -k "$IMGFILE" || { echo "❌ Не удалось распаковать."; exit 1; }
    IMGFILE="${IMGFILE%.gz}"
    echo "✅ Распаковано: $IMGFILE"
  else
    echo "❎ Shrink применим только к .img-файлам. Отмена."
    exit 0
  fi
fi
 
# 🛠 Проверка pishrink
if [[ ! -x "$SHRINK_SCRIPT" ]]; then
  echo "⚠️  shrink не найден. Загружаю..."
  if ! command -v curl &>/dev/null; then
    echo "❌ Требуется curl для загрузки pishrink."
    exit 1
  fi
  curl -fsSL https://raw.githubusercontent.com/Drewsif/pishrink/master/pishrink.sh -o "$SHRINK_SCRIPT"
  chmod +x "$SHRINK_SCRIPT"
fi
 
# 🧪 Создание резервной копии
# BACKUP_IMG="${IMGFILE%.img}_original.img"
# if [[ -f "$BACKUP_IMG" ]]; then
  # echo "⚠️ Резервная копия уже существует: $BACKUP_IMG"
# else
  # echo "📁 Создание резервной копии образа..."
  # cp --reflink=auto --sparse=always "$IMGFILE" "$BACKUP_IMG" || {
    # echo "❌ Не удалось создать копию."
    # exit 1
  # }
  # echo "✅ Резервная копия сохранена: $BACKUP_IMG"
# fi
 
# ❓ Одинарный или двойной shrink
echo "1 - Одинарный shrink"
echo "2 - Двойной shrink (рекомендуется)"
echo "0 - Отмена"
read -rp "👉 Выбор: " shrink_choice
[[ "$shrink_choice" == "0" ]] && echo "❎ Отменено." && $TEMP_MOUNTED && sudo umount "$TARGET_DIR" && exit 0
 
# 📏 Размер до
SIZE_BEFORE=$(du -h "$IMGFILE" | cut -f1)
 
# 🚀 Выполнение shrink
echo "⏳ Shrink #1..."
sudo "$SHRINK_SCRIPT" "$IMGFILE" || { echo "❌ Ошибка во время shrink."; exit 1; }
 
if [[ "$shrink_choice" == "2" ]]; then
  echo "🔁 Shrink #2..."
  sudo "$SHRINK_SCRIPT" "$IMGFILE" || { echo "❌ Ошибка во время второго shrink."; exit 1; }
fi
 
# 📏 Размер после
SIZE_AFTER=$(du -h "$IMGFILE" | cut -f1)
 
echo "✅ Завершено: Shrink выполнен$([[ "$shrink_choice" == "2" ]] && echo " дважды")"
echo "📦 Размер: $SIZE_BEFORE$SIZE_AFTER"
echo "📁 Резервная копия: $BACKUP_IMG"
 
$TEMP_MOUNTED && sudo umount "$TARGET_DIR"
projects/linux/manual_backup_scripts/shrink_img.1744012299.txt.gz · Последнее изменение: 2025/04/07 10:51 —

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