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

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


projects:linux:manual_backup_scripts:create_img

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
projects:linux:manual_backup_scripts:create_img [2025/04/08 00:29] projects:linux:manual_backup_scripts:create_img [2025/04/11 17:43] (текущий)
Строка 11: Строка 11:
 # ==DIS/AUTOEXEC== # ==DIS/AUTOEXEC==
 # === Create Img === # === Create Img ===
-# 04_create_image.sh — создание ограниченного образа с выбранного устройства Raspberry Pi +# 04_create_image.sh — создание ограниченного образа текущей системы Raspberry Pi 
-# с возможностью сохранить на внешний диск или сетевой ресурс (NAS)+# с отключением журналов для минимизации записей на SD карту
 # #
 +
 +echo "Снятие образа с live системы"
 +echo "──────────────────────────────"
  
 set -euo pipefail set -euo pipefail
  
-# --- Определение источника --- +# --- Поиск целевых устройств (включая NAS) ---
-echo "🗂️ Доступные источники (разделы с rootfs):" +
-mapfile -t SOURCES < <( +
-  lsblk -nrpo NAME,SIZE,FSTYPE,MOUNTPOINT | awk '/ext4/+
-    mount=$4; label="" +
-    if (mount == "/") label="екущая система)" +
-    printf("%s:%s:%s:%s%s\n", $1, $2, $3, mount, label) +
-  }' +
-+
- +
-if [[ ${#SOURCES[@]} -eq 0 ]]; then +
-  echo "❌ Нет доступных источников." +
-  exit 1 +
-fi +
- +
-i=1 +
-echo "" +
-for src in "${SOURCES[@]}"; do +
-  IFS=":" read -r dev size fs mp label <<< "$src" +
-  echo "$i - $dev ($size, $fs, $mp)$label" +
-  ((i++)) +
-done +
- +
-echo "0 - Отмена" +
-read -rp "🔍 Выберите устройство-источник: " choice +
-[[ "$choice" == "0" || -z "$choice" ]] && echo "❎ Отменено." && exit 0 +
-(( choice < 1 || choice > ${#SOURCES[@]} )) && echo "❌ Неверный выбор." && exit 1 +
- +
-SEL_SRC="${SOURCES[$((choice-1))]}" +
-IFS=":" read -r SRC_DEV SRC_SIZE SRC_FS SRC_MP SRC_LABEL <<< "$SEL_SRC" +
- +
-if [[ "$SRC_DEV" =~ ^(/dev/.+p[0-9]+)$ ]]; then +
-  SRC_PARENT=$(lsblk -no PKNAME "$SRC_DEV" | head -n1) +
-  SRC_PARENT="/dev/$SRC_PARENT" +
-else +
-  SRC_PARENT="$SRC_DEV" +
-fi +
- +
-# Проверка, что SRC_PARENT определён +
-if [[ -z "$SRC_PARENT" || "$SRC_PARENT" == "/dev/" ]]; then +
-  echo "❌ Не удалось определить родительское устройство." +
-  exit 1 +
-fi +
- +
-# --- Выбор цели ( диск/каталог ) ---+
 NAS_PATH="/mnt/backup_nas" NAS_PATH="/mnt/backup_nas"
 if mountpoint -q "$NAS_PATH"; then if mountpoint -q "$NAS_PATH"; then
Строка 75: Строка 34:
 fi fi
  
-echo "💿 Выберите место для сохранения образа:"+echo "💾 Выберите место для сохранения образа:"
 i=1 i=1
 for dev in "${DEVICES[@]}"; do for dev in "${DEVICES[@]}"; do
Строка 87: Строка 46:
  
 echo "0 - Отмена" echo "0 - Отмена"
-read -rp "🔍 Ваш выбор: " dchoice +read -rp "👉 Ваш выбор: " choice
-[[ "$dchoice" == "0" || -z "$dchoice" ]] && echo "❎ Отменено." && exit 0 +
-(( dchoice < 1 || dchoice > ${#DEVICES[@]} )) && echo "❌ Неверный выбор." && exit 1+
  
-SEL_DEV="${DEVICES[$((dchoice-1))]}"+if ! [[ "$choice" =~ ^[0-9]+$ ]] || (( choice < 1 || choice > ${#DEVICES[@]} )); then 
 +  echo "❎ Отменено или неверный ввод." 
 +  exit 0 
 +fi 
 + 
 +SEL_DEV="${DEVICES[$((choice-1))]}"
 IFS=":" read -r DEV_NAME DEV_SIZE DEV_MNT <<< "$SEL_DEV" IFS=":" read -r DEV_NAME DEV_SIZE DEV_MNT <<< "$SEL_DEV"
-TEMP_MOUNTED=false 
  
 +# Проверка на USB (влияние на сеть)
 +DEV_BUS=$(udevadm info -q property -n "$DEV_NAME" 2>/dev/null | grep ID_BUS= | cut -d= -f2 || true)
 +DEV_USB_DRIVER=$(udevadm info -q property -n "$DEV_NAME" 2>/dev/null | grep ID_USB_DRIVER= | cut -d= -f2 || true)
 +if [[ "${DEV_BUS:-}" == "usb" && "${DEV_USB_DRIVER:-}" =~ "usb-storage" ]]; then
 +  echo "⚠️ Внимание: Устройство подключено через USB."
 +  echo "   Если используется USB 3.0 — возможны отказы сети (Ethernet) во время записи."
 +  echo "   Рекомендуется использовать NAS или USB 2.0 для надёжности."
 +  echo ""
 +fi
 +
 +# Определение целевого каталога
 +TEMP_MOUNTED=false
 if [[ "$DEV_NAME" == "$NAS_PATH" ]]; then if [[ "$DEV_NAME" == "$NAS_PATH" ]]; then
   TARGET_DIR="$NAS_PATH"   TARGET_DIR="$NAS_PATH"
Строка 113: Строка 86:
     FIRST_PART=$(lsblk -nrpo NAME "$DEV_NAME" | grep -v "^$DEV_NAME" | head -n1)     FIRST_PART=$(lsblk -nrpo NAME "$DEV_NAME" | grep -v "^$DEV_NAME" | head -n1)
     if [[ -z "$FIRST_PART" ]]; then     if [[ -z "$FIRST_PART" ]]; then
-      echo "❌ Не найден раздел."+      echo "❌ Не найден раздел на выбранном устройстве."
       exit 1       exit 1
     fi     fi
     if sudo mount "$FIRST_PART" "$MNT_PATH"; then     if sudo mount "$FIRST_PART" "$MNT_PATH"; then
 +      echo "✅ Раздел $FIRST_PART примонтирован в $MNT_PATH"
       TARGET_DIR="$MNT_PATH"       TARGET_DIR="$MNT_PATH"
       TEMP_MOUNTED=true       TEMP_MOUNTED=true
     else     else
-      echo "❌ Не удалось примонтировать."+      echo "❌ Не удалось примонтировать $FIRST_PART."
       exit 1       exit 1
     fi     fi
Строка 126: Строка 100:
 fi fi
  
-# --- Выбор имени файла ---+# --- Подготовка имени файла ---
 DATE=$(date +%F_%H-%M-%S) DATE=$(date +%F_%H-%M-%S)
 echo "" echo ""
Строка 156: Строка 130:
 FINAL_IMG="$TARGET_DIR/$IMG_NAME" FINAL_IMG="$TARGET_DIR/$IMG_NAME"
  
-END_SECTOR=$(sudo fdisk -"$SRC_PARENT" | awk -v dev="$SRC_DEV'$1 ~ dev { end=$3 } END { print end }') +# --- Проверка перезаписи --- 
-SECTOR_SIZE=$(sudo blockdev --getss "$SRC_PARENT")+if [[ -f "$FINAL_IMG" ]]; then 
 +  echo "⚠️ Файл уже существует: $FINAL_IMG" 
 +  read -rp "❗ Перезаписать? [y/N]: " overwrite 
 +  [[ "${overwrite,,}" != "y" ]] && echo "❎ Отменено." && exit 0 
 +fi 
 + 
 +# --- Остановка сервисов --- 
 +echo "[*] Остановка логов и фоновых сервисов..." 
 +SERVICES=("rsyslog" "systemd-journald" "apt-daily.timer" "docker"
 +for svc in "${SERVICES[@]}"; do 
 +  if systemctl is-active --quiet "$svc"; then 
 +    echo "⏸️  Останавливаю $svc..." 
 +    sudo systemctl stop "$svc" || true 
 +  fi 
 +done 
 +sync 
 +sudo sysctl -w vm.drop_caches=3 >/dev/null || true 
 + 
 +# --- Расчёт объёма --- 
 +echo "[*] Определение размера /dev/mmcblk0..." 
 +END_SECTOR=$(sudo fdisk -l /dev/mmcblk0 | awk '/mmcblk0p[0-9]+/ { end=$3 } END { print end }') 
 +SECTOR_SIZE=$(sudo blockdev --getss /dev/mmcblk0)
 TOTAL_BYTES=$(( (END_SECTOR + 1) * SECTOR_SIZE )) TOTAL_BYTES=$(( (END_SECTOR + 1) * SECTOR_SIZE ))
 TOTAL_MB=$(( (TOTAL_BYTES + 1024*1024 - 1) / (1024*1024) + 16 )) TOTAL_MB=$(( (TOTAL_BYTES + 1024*1024 - 1) / (1024*1024) + 16 ))
  
 +# --- Снятие образа ---
 echo "[*] Снимаю образ: $FINAL_IMG ($TOTAL_MB МБ)..." echo "[*] Снимаю образ: $FINAL_IMG ($TOTAL_MB МБ)..."
-sudo dd if="$SRC_PARENT" of="$FINAL_IMG" bs=1M count="$TOTAL_MB" status=progress+sudo dd if=/dev/mmcblk0 of="$FINAL_IMG" bs=1M count="$TOTAL_MB" status=progress
 sync sync
  
 +# --- Проверка ---
 if sudo fdisk -l "$FINAL_IMG" >/dev/null 2>&1; then if sudo fdisk -l "$FINAL_IMG" >/dev/null 2>&1; then
   echo "✅ Образ сохранён: $FINAL_IMG"   echo "✅ Образ сохранён: $FINAL_IMG"
Строка 172: Строка 169:
 fi fi
  
-Корректная проверка на необходимость размонтирования+--- Очистка ---
 if $TEMP_MOUNTED; then if $TEMP_MOUNTED; then
-  sudo umount "$TARGET_DIR"+  sudo umount "$TARGET_DIR" && sudo rmdir "$TARGET_DIR"
 fi fi
 +
 +# --- Восстановление сервисов ---
 +echo "[*] Восстановление остановленных сервисов..."
 +for svc in "${SERVICES[@]}"; do
 +  echo "▶️  Запуск $svc..."
 +  sudo systemctl start "$svc" || echo "⚠️  Не удалось запустить $svc"
 +done
  
 exit 0 exit 0
  
 </code> </code>
 +===== ******* =====
 +[[https://boosty.to/takraztak/donate|Поддержать через Boosty]]
projects/linux/manual_backup_scripts/create_img.1744061365.txt.gz · Последнее изменение: 2025/04/08 00:29 —

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