#!/usr/bin/env bash # collect-on-device.sh — выполняется НА РЕФЕРЕНС-устройстве (на столе, с интернетом). # Качает в /tmp/btdebs ровно те пакеты, которых не хватает голому target-устройству. # # Рядом ожидает (заливаются через adb из collect-debs.ps1): # packages.list — что хотим в рантайме # target-installed.txt — что УЖЕ стоит на голом устройстве (опционально) set -euo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" OUT=/tmp/btdebs PKGS_FILE="$HERE/packages.list" TGT="$HERE/target-installed.txt" [ "$(id -u)" -eq 0 ] || { echo "[error] нужен root (adb root или sudo)"; exit 1; } [ -f "$PKGS_FILE" ] || { echo "[error] нет packages.list"; exit 1; } rm -rf "$OUT"; mkdir -p "$OUT" export DEBIAN_FRONTEND=noninteractive export LANG=C LC_ALL=C # сообщения apt на английском, а не иероглифами echo "[collect] apt-get update (нужен интернет на этом устройстве)..." # Acquire::Check-Valid-Until=false — принимаем устаревшие Release (зеркало давно не обновляло) # || true — не валимся из-за битых репо (напр. bullseye-backports 404); пакеты берём из main apt-get -o Acquire::Check-Valid-Until=false update || true WANT="$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$PKGS_FILE" | tr '\n' ' ')" [ -n "$WANT" ] || { echo "[error] packages.list пуст"; exit 1; } echo "[collect] считаю рекурсивное замыкание зависимостей..." CLOSURE="$(apt-cache depends --recurse \ --no-recommends --no-suggests --no-conflicts \ --no-breaks --no-replaces --no-enhances $WANT \ | awk '/^[a-zA-Z0-9]/{print $1}' | sed 's/:.*//' | sort -u)" if [ -f "$TGT" ]; then echo "[collect] вычитаю пакеты, уже стоящие на целевом (голом) устройстве..." BASE="$(sed 's/:.*//' "$TGT" | sort -u)" else echo "[collect] target-installed.txt не передан — вычитаю то, что стоит здесь" BASE="$(dpkg-query -W -f='${Package}\n' 2>/dev/null | sed 's/:.*//' | sort -u)" fi MISSING="$(comm -23 <(printf '%s\n' "$CLOSURE") <(printf '%s\n' "$BASE"))" # исключаем альтернативы, конфликтующие с тем, что уже стоит на устройстве: # *-gles — GLES-варианты Qt (конфликтуют с обычными libqt5*), # elogind — альтернатива systemd-logind (конфликтует с systemd) MISSING="$(printf '%s\n' "$MISSING" | grep -vE -- '-gles$|^elogind$|^libelogind0$|^libpam-elogind$' || true)" cd "$OUT" ok=0; skip=0 for p in $MISSING; do if apt-get download "$p" >/dev/null 2>&1; then ok=$((ok+1)); else skip=$((skip+1)); fi done echo "[collect] скачано: $ok, пропущено (виртуальные/недоступные): $skip" ls "$OUT"/*.deb >/dev/null 2>&1 || { echo "[error] ни одного .deb не скачалось"; exit 1; } echo "COLLECT-OK"