Action unknown: copypageplugin__copy
projects:linux:manual_backup_scripts:shrink_img
Shrink Image
Входит в набор rPi Seal
Обрезает размер образа до фактически занимаемого данными размера.
После записи на SD карты при первом запуске система зразворачивается на весь доступный объем карты.
- shrink_image.sh
#!/bin/bash export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8 # ==DIS/AUTOEXEC== # ===Shrink image=== # 05_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 trap '[[ $TEMP_MOUNTED == true ]] && sudo umount "$TARGET_DIR"' EXIT 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" 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 "❎ Отменено." && 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 "❎ Отменено." && 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 "📁 Резервная копия: $BACKUP_IMG" echo "📦 Размер: $SIZE_BEFORE → $SIZE_AFTER"
*******
projects/linux/manual_backup_scripts/shrink_img.txt · Последнее изменение: 2025/04/11 17:46 —