← Tous les projets
🐧

Linux Kernel Scripts

Scripts Bash pour fiabiliser le cycle de vie des noyaux Linux Mint.

BashLinuxLinux MintRed HatAPTGRUB 2Git

Ce que le projet démontre

Maintenance noyau

Inventaire, mise à jour et nettoyage contrôlé des versions installées.

Dry-run

Simulation complète avant toute modification du système.

Rollback

Conservation d’une stratégie de retour arrière avec GRUB.

Journalisation

Historique horodaté des décisions et commandes exécutées.

Description

Linux Kernel Scripts est une suite d’outils Bash destinée à encadrer les opérations sensibles autour des noyaux Linux Mint. Le principe est de rendre chaque action lisible, vérifiable et réversible avant de toucher au système.

Les scripts utilisent le strict mode Bash, distinguent clairement simulation et exécution réelle, et demandent une confirmation avant les étapes destructives. Le nettoyage conserve toujours des noyaux de secours afin de limiter le risque après une mise à jour.

La journalisation permet de retrouver ce qui a été détecté, installé ou supprimé. Le projet illustre une approche d’administration système basée sur l’automatisation prudente plutôt que sur une succession de commandes manuelles.

Fonctionnalités & points techniques

  • ▹Détection des noyaux installés et disponibles.
  • ▹Installation contrôlée avec vérifications préalables.
  • ▹Nettoyage des versions obsolètes tout en conservant un secours.
  • ▹Mode --dry-run pour prévisualiser toutes les actions.
  • ▹Bash strict mode : set -Eeuo pipefail.
  • ▹Confirmation avant les opérations destructives.
  • ▹Journalisation horodatée des opérations.
  • ▹Aide au rollback et gestion de GRUB.

Extraits des scripts Kernel Auto Cleaner PRO et fullupdate

Extraits représentatifs de Kernel Auto Cleaner PRO v5.7, un script Bash d’administration destiné à sécuriser la maintenance, la conservation et le nettoyage des noyaux Linux. Le script fullupdate v1.5 complète l’ensemble en orchestrant les mises à jour APT, deb-get, Flatpak, Snap, firmware et pipx.

Initialisation, journalisation et verrouillage

Strict mode Bash, journalisation, rotation des logs, verrouillage exclusif et gestion de la ligne de commande.

BASH
kernel_auto_cleaner_pro.txt · lignes 1–115
#!/usr/bin/env bash# =============================================================================# kernel_auto_cleaner_pro — v5.7# -----------------------------------------------------------------------------# Changelog v5.7 vs v5.6 (correctifs issus des tests sur machine réelle):#  - set -e: header() et check_boot_full() n'utilisent plus `[[ ]] && log`#            (le script s'arrêtait juste après le header hors dry-run)#  - set -e: `(( ++REMOVED_COUNT ))` au lieu de `(( REMOVED_COUNT++ ))`#            (le post-incrément valait 0 au 1er kernel purgé -> arrêt du script)#  - Dry-run: ensure_headers_for / ensure_modules_extra_for n'appellent plus apt#  - apt update/install/purge: sortie capturée via log() + DEBIAN_FRONTEND=noninteractive#  - apt autoremove: uniquement si au moins un kernel est à supprimer#  - modules-extra: test du Candidate réel (apt-cache policy, LC_ALL=C) au lieu de#            apt-cache show, qui réussit pour un paquet sans version installable#  - GRUB: grub-set-default ignoré si GRUB_DEFAULT n'est pas "saved" (sans effet sinon)#  - KEEP_BRANCH6_PREFIX="6.8": conserve le kernel GA 24.04 (support jusqu'en 2029)#            et non plus "le dernier 6.x", qui peut être un HWE abandonné# -----------------------------------------------------------------------------# Changelog v5.6 vs v5.5:#  - DRYRUN: standardise toutes les comparaisons sur [[ "$DRYRUN" == "true" ]]#            (plus de $DRYRUN || ... mélangé avec [[ "$DRYRUN" == true ]])#  - rotate_log() extraite de header() (séparation des responsabilités)#  - CLI: --help, --version, --keep-kernels N#  - Attente du verrou APT (apt_wait_lock) avant chaque appel apt#  - apt_install_safe: --no-install-recommends par défaut#  - stats(): compteur de kernels supprimés affiché#  - Trap SIGINT/SIGTERM pour sortie propre#  - clean_apt_kernel_archives: suppression du double-check keep_regex redondant#  - Messages de log uniformisés en anglais#  - detect_kernels: sed simplifié en une passe#  - Correction: flock libère correctement le lockfile à EXIT# =============================================================================set -Eeuo pipefailIFS=$'\n\t'VERSION="5.7"HOST="$(hostname)"LOG="/var/log/kernel_cleaner.log"LOCKFILE="/run/kernel_auto_cleaner.lock"# ---- Logging ----------------------------------------------------------------log() {  local ts  ts="$(date +"%F %T")"  echo "[$ts] $*" | tee -a "$LOG"}die() {  log "ERROR: $*"  exit 1}# ---- Log rotation (séparée de header) ---------------------------------------rotate_log() {  if [[ -f "$LOG" ]]; then    local size    size="$(stat -c%s "$LOG" 2>/dev/null || echo 0)"    if (( size > 1048576 )); then      local rotated="$LOG.$(date +%Y%m%d%H%M%S)"      mv "$LOG" "$rotated"      gzip -f "$rotated" 2>/dev/null || true    fi  fi}# ---- Lock -------------------------------------------------------------------acquire_lock() {  exec 9>"$LOCKFILE"  # Libère le lockfile à la sortie (succès ou erreur)  trap 'rm -f "$LOCKFILE"; exit' EXIT INT TERM  if ! flock -n 9; then    echo "Another instance is running (lock: $LOCKFILE)"    exit 1  fi}# ---- CLI --------------------------------------------------------------------usage() {  cat <<EOFUsage: $(basename "$0") [OPTIONS]Options:  --dry-run            Simulate all actions, no changes applied  --keep-kernels N     Number of recent kernels to keep (default: $KEEP_KERNELS)  --version            Print version and exit  --help               Show this helpEOF  exit 0}# ---- Policy -----------------------------------------------------------------SAFE_VMWARE_PREFIX="7.0"KEEP_BRANCH6_PREFIX="6.8"   # kernel GA Ubuntu 24.04, supporté jusqu en 2029KEEP_KERNELS=1AUTO_INSTALL_SAFE_KERNEL=trueAUTO_MARK_SAFE_MANUAL=trueDO_VBOX_REBUILD=trueDO_VMWARE_REBUILD=trueBOOT_WARN_PCT=90DRYRUN=false# Parse argumentswhile [[ $# -gt 0 ]]; do  case "${1:-}" in    --dry-run)        DRYRUN=true ;;    --keep-kernels)   shift; KEEP_KERNELS="${1:?'--keep-kernels requires a value'}" ;;    --version)        echo "kernel_auto_cleaner_pro v$VERSION"; exit 0 ;;    --help|-h)        usage ;;    *)                echo "Unknown option: $1"; usage ;;  esac  shiftdone

Gestion sécurisée d’APT

Attente des verrous APT et fonctions sécurisées pour les mises à jour, installations et suppressions.

BASH
kernel_auto_cleaner_pro.txt · lignes 116–189
# ---- Helpers ----------------------------------------------------------------header() {  echo  echo "=========================================="  echo " Kernel Auto Cleaner PRO v$VERSION"  echo " Host: $HOST"  echo "=========================================="  echo " Running kernel: $(uname -r)"  echo "=========================================="  # NE PAS utiliser [[ ]] && log : si DRYRUN=false, la fonction retourne 1  # et set -e arrête le script juste après le header.  if [[ "$DRYRUN" == "true" ]]; then    log "DRY RUN mode — no changes will be applied"  fi}require_root() {  if [[ ${EUID} -ne 0 ]]; then    echo "Run as root"    exit 1  fi}has_cmd() { command -v "$1" >/dev/null 2>&1; }pkg_installed() {  dpkg-query -W -f='${Status}\n' "$1" 2>/dev/null | grep -q "install ok installed"}# Attend que le verrou APT soit libéré (max 120s)apt_wait_lock() {  local i=0  while fuser /var/lib/dpkg/lock-frontend /var/cache/apt/archives/lock >/dev/null 2>&1; do    if (( i == 0 )); then      log "Waiting for APT lock..."    fi    sleep 5    (( i += 5 ))    if (( i >= 120 )); then      log "WARNING: APT lock still held after 120s — proceeding anyway"      break    fi  done}apt_update_safe() {  apt_wait_lock  local out  # DEBIAN_FRONTEND=noninteractive empêche apt d'écrire directement sur /dev/tty  if ! out="$(DEBIAN_FRONTEND=noninteractive apt-get update -qq 2>&1)"; then    log "WARNING: apt update failed"    [[ -n "$out" ]] && log "  Detail: $out"  fi}# --no-install-recommends évite d'installer des paquets non essentielsapt_install_safe() {  apt_wait_lock  local out  if ! out="$(DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$@" 2>&1)"; then    log "WARNING: install failed for packages: $*"    log "  Detail: $out"  fi}apt_purge_safe() {  apt_wait_lock  local out  if ! out="$(DEBIAN_FRONTEND=noninteractive apt-get purge -y "$@" 2>&1)"; then    log "WARNING: purge failed for packages: $*"    log "  Detail: $out"  fi}

Détection et protection des noyaux

Inventaire des noyaux, détection HWE et constitution de l’ensemble des noyaux protégés.

BASH
kernel_auto_cleaner_pro.txt · lignes 224–325
# ---- HWE detection ----------------------------------------------------------detect_hwe() {  local metas  metas="$(dpkg-query -W -f='${Package}\n' \    'linux-generic-hwe-*' 'linux-image-generic-hwe-*' 'linux-headers-generic-hwe-*' \    2>/dev/null || true)"  if [[ -n "$metas" ]]; then    log "HWE meta packages detected:"    printf "%s\n" "$metas" | tee -a "$LOG" >/dev/null || true  else    log "HWE meta packages: none detected"  fi  local mint_hwe  mint_hwe="$(dpkg-query -W -f='${Package}\n' 'linux-hwe-*' 2>/dev/null | head -n 50 || true)"  if [[ -n "$mint_hwe" ]]; then    log "Mint/Ubuntu HWE-related packages detected (linux-hwe-*):"    printf "%s\n" "$mint_hwe" | tee -a "$LOG" >/dev/null || true  fi}# ---- Kernel discovery -------------------------------------------------------detect_kernels() {  CURRENT_KERNEL="$(uname -r)"  # Une seule passe sed pour strip linux-image- et unsigned-  mapfile -t INSTALLED_KERNELS < <(    dpkg-query -W -f='${Package}\n' 'linux-image-*' 2>/dev/null \      | sed -E 's/^linux-image-(unsigned-)?//' \      | grep -E '^[0-9]' \      | sort -u -V  )  SAFE_KERNEL=""  if (( ${#INSTALLED_KERNELS[@]} > 0 )); then    SAFE_KERNEL="$(printf "%s\n" "${INSTALLED_KERNELS[@]}" \      | grep -E "^${SAFE_VMWARE_PREFIX//./\\.}" \      | tail -n1 || true)"  fi}detect_mainline_kernel() {  if [[ "$CURRENT_KERNEL" =~ 0[0-9]{5} ]]; then    log "Mainline kernel detected: $CURRENT_KERNEL"    log "Warning: mainline kernels may break DKMS builds"  fi}detect_virtualization() {  HAS_VMWARE=false  HAS_VBOX=false  has_cmd vmware-modconfig || has_cmd vmware && HAS_VMWARE=true || true  has_cmd vboxmanage && HAS_VBOX=true || true}check_secureboot() {  if has_cmd mokutil; then    if mokutil --sb-state 2>/dev/null | grep -qi enabled; then      log "WARNING: SecureBoot enabled — unsigned modules may fail to load (VMware/VBox DKMS)"    fi  fi}# ---- Branch 6.x retention --------------------------------------------------detect_branch6_kernel() {  BRANCH6_KERNEL=""  [[ -z "${KEEP_BRANCH6_PREFIX:-}" ]] && return 0  (( ${#INSTALLED_KERNELS[@]} > 0 )) || return 0  local prefix_re="^${KEEP_BRANCH6_PREFIX//./\\.}\."  BRANCH6_KERNEL="$(printf "%s\n" "${INSTALLED_KERNELS[@]}" \    | grep -E "$prefix_re" \    | tail -n1)" || BRANCH6_KERNEL=""  if [[ -n "$BRANCH6_KERNEL" ]]; then    log "Branch ${KEEP_BRANCH6_PREFIX}.x retention: keeping $BRANCH6_KERNEL"  else    log "Branch ${KEEP_BRANCH6_PREFIX}.x retention: no kernel found"  fi}protect_kernels() {  PROTECTED_KERNELS=("$CURRENT_KERNEL")  if [[ -n "${SAFE_KERNEL:-}" && "${SAFE_KERNEL}" != "${CURRENT_KERNEL}" ]]; then    PROTECTED_KERNELS+=("$SAFE_KERNEL")  fi  if [[ -n "${BRANCH6_KERNEL:-}" \     && "${BRANCH6_KERNEL}" != "${CURRENT_KERNEL}" \     && "${BRANCH6_KERNEL}" != "${SAFE_KERNEL:-}" ]]; then    PROTECTED_KERNELS+=("$BRANCH6_KERNEL")    log "Branch 6.x kernel added to protected set: $BRANCH6_KERNEL"  fi}is_protected_kernel() {  local k="$1" p  for p in "${PROTECTED_KERNELS[@]}"; do    [[ "$k" == "$p" ]] && return 0  done  return 1}

Politique de purge sécurisée

Sélection des noyaux conservés, protections de sécurité et nettoyage contrôlé des anciennes versions.

BASH
kernel_auto_cleaner_pro.txt · lignes 381–472
# ---- Purge policy -----------------------------------------------------------REMOVED_COUNT=0purge_old_kernels() {  log "Active kernel  : $CURRENT_KERNEL"  log "VMware-safe    : ${SAFE_KERNEL:-none}"  if (( ${#INSTALLED_KERNELS[@]} == 0 )); then    log "No installed kernel packages detected. Skipping kernel purge."    return 0  fi  mapfile -t NEWEST < <(printf "%s\n" "${INSTALLED_KERNELS[@]}" | tail -n "$KEEP_KERNELS")  KEEP_SET=()  KEEP_SET+=("${NEWEST[@]}")  KEEP_SET+=("${PROTECTED_KERNELS[@]}")  mapfile -t KEEP_SET < <(printf "%s\n" "${KEEP_SET[@]}" | sort -u -V)  (( ${#KEEP_SET[@]} >= 1 )) || die "Safety check failed: KEEP_SET is empty"  printf "%s\n" "${KEEP_SET[@]}" | grep -qx "$CURRENT_KERNEL" \    || die "Safety check failed: current kernel not in KEEP_SET"  log "Installed kernels    : ${INSTALLED_KERNELS[*]}"  log "Protected kernels    : ${PROTECTED_KERNELS[*]}"  log "Kernels to keep      : ${KEEP_SET[*]}"  mapfile -t TO_REMOVE < <(    printf "%s\n" "${INSTALLED_KERNELS[@]}" \    | sort -u -V \    | grep -vxFf <(printf "%s\n" "${KEEP_SET[@]}") || true  )  if (( ${#TO_REMOVE[@]} == 0 )); then    log "No kernels to remove"  else    log "Kernels to remove    : ${TO_REMOVE[*]}"  fi  local k pkgs p  local candidates  for k in "${TO_REMOVE[@]}"; do    [[ "$k" == "$CURRENT_KERNEL" ]] && { log "HARD STOP: refusing to purge running kernel: $k"; continue; }    log "Purging kernel: $k"    pkgs=()    candidates=(      "linux-image-$k"      "linux-image-unsigned-$k"      "linux-modules-$k"      "linux-modules-extra-$k"      "linux-headers-$k"      "linux-tools-$k"      "linux-cloud-tools-$k"    )    for p in "${candidates[@]}"; do      pkg_installed "$p" && pkgs+=("$p")    done    if (( ${#pkgs[@]} == 0 )); then      log "No installed packages found for kernel: $k"      continue    fi    log "Packages: ${pkgs[*]}"    if [[ "$DRYRUN" == "true" ]]; then      log "[DRYRUN] Would purge: ${pkgs[*]}"    else      apt_purge_safe "${pkgs[@]}"      # (( REMOVED_COUNT++ )) évalue à 0 quand count=0 → exit code 1 → set -e crashe      # (( ++REMOVED_COUNT )) évalue à la NOUVELLE valeur (≥1) → exit code 0      (( ++REMOVED_COUNT ))    fi  done  if (( ${#TO_REMOVE[@]} > 0 )); then    if [[ "$DRYRUN" == "true" ]]; then      log "[DRYRUN] Would run: apt autoremove"    else      apt-get autoremove -y >/dev/null 2>&1 || true    fi  fi}is_kept_kernel() {  local k="$1"  printf "%s\n" "${KEEP_SET[@]}" | grep -qx "$k"}

DKMS et virtualisation

Contrôles DKMS et reconstruction des modules VMware et VirtualBox après évolution du noyau.

BASH
kernel_auto_cleaner_pro.txt · lignes 648–757
# ---- DKMS ------------------------------------------------------------------clean_dkms() {  has_cmd dkms || return 0  log "DKMS status:"  dkms status 2>/dev/null | tee -a "$LOG" >/dev/null || true}clean_broken_dkms() {  has_cmd dkms || return 0  log "Checking DKMS broken modules (missing dkms.conf)"  local mod ver src  shopt -s nullglob  for mod in /var/lib/dkms/*; do    [[ -d "$mod" ]] || continue    mod="$(basename "$mod")"    for ver in /var/lib/dkms/"$mod"/*; do      [[ -d "$ver" ]] || continue      ver="$(basename "$ver")"      src="/var/lib/dkms/$mod/$ver/source/dkms.conf"      if [[ ! -f "$src" ]]; then        log "Broken DKMS module: $mod/$ver (missing dkms.conf)"        if [[ "$DRYRUN" == "true" ]]; then          log "[DRYRUN] Would run: dkms remove \"$mod/$ver\" --all"        else          dkms remove "$mod/$ver" --all >/dev/null 2>&1 || true          rm -rf "/var/lib/dkms/$mod/$ver"        fi      fi    done  done  shopt -u nullglob}clean_dkms_orphans() {  log "Checking DKMS orphan builds"  shopt -s nullglob  local mod ver build k  for mod in /var/lib/dkms/*; do    [[ -d "$mod" ]] || continue    mod="$(basename "$mod")"    for ver in /var/lib/dkms/"$mod"/*; do      [[ -d "$ver" ]] || continue      ver="$(basename "$ver")"      for build in /var/lib/dkms/"$mod"/"$ver"/*; do        [[ -d "$build" ]] || continue        k="$(basename "$build")"        [[ "$k" == "source" || "$k" == "build" || "$k" == "kernel" ]] && continue        if [[ ! -d "/lib/modules/$k" && ! -d "/usr/lib/modules/$k" ]]; then          log "Removing DKMS orphan build: $mod/$ver/$k"          if [[ "$DRYRUN" == "true" ]]; then            log "[DRYRUN] Would remove: $build"          else            rm -rf "$build"          fi        fi      done    done  done  shopt -u nullglob}# ---- Virtualization rebuild -------------------------------------------------rebuild_virtualbox() {  [[ "$DO_VBOX_REBUILD" == "true" ]] || return 0  "$HAS_VBOX" || return 0  log "Rebuilding VirtualBox modules"  ensure_headers_for "$CURRENT_KERNEL"  if [[ "$DRYRUN" == "true" ]]; then    log "[DRYRUN] Would run: /sbin/vboxconfig"; return 0  fi  if [[ -x /sbin/vboxconfig ]]; then    /sbin/vboxconfig >/dev/null 2>&1 || true  else    log "VirtualBox: /sbin/vboxconfig not found (skip)"; return 0  fi  modinfo -k "$CURRENT_KERNEL" vboxdrv >/dev/null 2>&1 \    && log "VirtualBox modules OK" \    || log "WARNING: VirtualBox modules missing"}rebuild_vmware() {  [[ "$DO_VMWARE_REBUILD" == "true" ]] || return 0  "$HAS_VMWARE" || return 0  if [[ -n "${SAFE_KERNEL:-}" && "$CURRENT_KERNEL" != "$SAFE_KERNEL" ]]; then    log "WARNING: Current kernel is not VMware-safe: $CURRENT_KERNEL"    log "         Recommended VMware-safe kernel: $SAFE_KERNEL"  fi  log "Rebuilding VMware modules"  ensure_headers_for "$CURRENT_KERNEL"  if [[ "$DRYRUN" == "true" ]]; then    log "[DRYRUN] Would install build-essential gcc make perl dkms"    log "[DRYRUN] Would run: vmware-modconfig --console --install-all"; return 0  fi  apt_install_safe build-essential gcc make perl dkms  vmware-modconfig --console --install-all >/dev/null 2>&1 || true  modinfo -k "$CURRENT_KERNEL" vmmon >/dev/null 2>&1 \    && log "VMware modules OK" \    || log "WARNING: VMware modules missing"  local VMWARE_VERSION  VMWARE_VERSION="$(vmware --version 2>/dev/null | awk '{print $3}' || true)"  [[ -n "$VMWARE_VERSION" ]] && log "VMware version: $VMWARE_VERSION"}

Nettoyage APT, statistiques et programme principal

Nettoyage final, statistiques d’exécution et orchestration générale du script.

BASH
kernel_auto_cleaner_pro.txt · lignes 758–849
# ---- APT cache cleanup ------------------------------------------------------clean_apt_kernel_archives() {  local cache="/var/cache/apt/archives"  [[ -d "$cache" ]] || return 0  log "Cleaning APT kernel archives not in KEEP_SET"  shopt -s nullglob  local f base ver  for f in "$cache"/linux-*.deb; do    base="$(basename "$f")"    # Extrait la version depuis le nom du paquet    if [[ "$base" =~ ^linux-(image|modules|modules-extra|headers|tools)-([0-9]+\.[0-9]+\.[0-9]+-[0-9]+(\.[0-9]+)?-generic)_.*\.deb$ ]]; then      ver="${BASH_REMATCH[2]}"      # Garde si présent dans KEEP_SET (qui inclut déjà CURRENT_KERNEL)      if printf "%s\n" "${KEEP_SET[@]}" | grep -qx "$ver"; then        continue      fi      log "Removing cached deb: $f"      if [[ "$DRYRUN" == "true" ]]; then        log "[DRYRUN] Would remove: $f"      else        rm -f "$f" || true      fi    fi  done  shopt -u nullglob}# ---- Stats ------------------------------------------------------------------stats() {  local after freed  after="$(du -sb /boot /lib/modules /usr/lib/modules 2>/dev/null | awk '{s+=$1} END{print s+0}')"  freed=$(( BEFORE_SIZE - after ))  if (( freed < 0 )); then    log "Space change: +$(( -freed )) bytes used (new kernel installed?)"  else    log "Space freed: $freed bytes"  fi  log "Kernels removed: $REMOVED_COUNT"}# ---- Main -------------------------------------------------------------------main() {  rotate_log  header  require_root  acquire_lock  check_boot_full  fix_dpkg_state  detect_hwe  BEFORE_SIZE="$(du -sb /boot /lib/modules /usr/lib/modules 2>/dev/null | awk '{s+=$1} END{print s+0}')"  detect_kernels  detect_mainline_kernel  detect_virtualization  check_secureboot  ensure_safe_kernel_installed  detect_kernels  detect_branch6_kernel  protect_kernels  purge_old_kernels  clean_orphan_modules  clean_boot  protect_grub_default_current_kernel  refresh_boot  clean_dkms  clean_broken_dkms  clean_dkms_orphans  intel_wifi_fallback  rebuild_virtualbox  rebuild_vmware  # Snapshot DKMS final après rebuilds  clean_dkms  clean_dkms_orphans  clean_apt_kernel_archives  check_boot_full  stats  log "Kernel cleaner completed successfully"}main "$@"

fullupdate : initialisation et verrouillage

Strict mode Bash, options --dry-run, vérification root, rotation du journal, journalisation horodatée et verrou exclusif.

BASH
fullupdate.txt · lignes 1–99
#!/usr/bin/env bash# -----------------------------------------------------------------------------# fullupdate - System update utility# Version: 1.5 "deb-get cache sync + Flatpak XDG"# -----------------------------------------------------------------------------# Changelog v1.5 vs v1.4:#  - Reboot: kernel le plus récent détecté par tri de version (sort -V) au lieu#    de la date de modification (ls -t), qui désignait à tort un kernel plus#    ancien installé après un plus récent (ex. 6.8 installé après 7.0)# -----------------------------------------------------------------------------# Changelog v1.4 vs v1.3:#  - deb-get: utilise DEBGET_TOKEN déjà chargé dans l'environnement#  - deb-get: fallback sécurisé vers /etc/deb-get/token#  - Suppression de l'ancien chemin /root/.config/deb-get/token#  - deb-get: attente de la reconstruction asynchrone du cache après update#  - Utilise le verrou natif /var/cache/deb-get/updating_supported.lock#  - Vérifie supported.list et supported_apps.list avant upgrade#  - Timeout deb-get cache fixé à 120 secondes#  - Aucun nettoyage automatique de /var/cache/deb-get#  - Flatpak user: fournit HOME, XDG_DATA_HOME et XDG_DATA_DIRS explicitement#    afin d'inclure les exports Flatpak utilisateur et système# -----------------------------------------------------------------------------set -Eeuo pipefailVERSION="1.5"LOG_FILE="/var/log/fullupdate.log"LOCK_FILE="/run/fullupdate.lock"MAX_SIZE=1048576  # 1 MBDRYRUN=falseSTART_TIME=$(date +%s)# -----------------------------------------------------------------------------# CLI# -----------------------------------------------------------------------------while [[ $# -gt 0 ]]; do  case "${1:-}" in    --dry-run)      DRYRUN=true      ;;    --version)      echo "fullupdate v$VERSION"      exit 0      ;;    --help|-h)      echo "Usage: $(basename "$0") [--dry-run] [--version] [--help]"      exit 0      ;;    *)      echo "Unknown option: $1"      exit 1      ;;  esac  shiftdone# -----------------------------------------------------------------------------# Root check# -----------------------------------------------------------------------------if [[ $EUID -ne 0 ]]; then  echo "Please run as root: sudo $0"  exit 1fiexport HOME=/rootexport USER=rootexport LOGNAME=root# -----------------------------------------------------------------------------# Log rotation# -----------------------------------------------------------------------------if [[ -f "$LOG_FILE" && $(stat -c%s "$LOG_FILE") -gt $MAX_SIZE ]]; then  local_rot="${LOG_FILE}.$(date +%Y%m%d%H%M%S)"  mv "$LOG_FILE" "$local_rot"  gzip -f "$local_rot" 2>/dev/null || truefiexec > >(tee -a "$LOG_FILE") 2>&1log() {  echo "[$(date +"%F %T")] $*"}# -----------------------------------------------------------------------------# Lock fullupdate# -----------------------------------------------------------------------------exec 9>"$LOCK_FILE" || {  echo "Cannot open lock file $LOCK_FILE"  exit 1}trap 'rm -f "$LOCK_FILE"' EXIT INT TERMif ! flock -n 9; then  log "Another instance is already running (lock: $LOCK_FILE)"  exit 1fi

fullupdate : verrous APT et jeton deb-get

Attente du verrou APT, chargement sécurisé du jeton GitHub et attente de la reconstruction du cache deb-get.

BASH
fullupdate.txt · lignes 100–175
# -----------------------------------------------------------------------------# Attente verrou APT# -----------------------------------------------------------------------------apt_wait_lock() {  local i=0  while fuser \    /var/lib/dpkg/lock-frontend \    /var/cache/apt/archives/lock \    >/dev/null 2>&1  do    if (( i == 0 )); then      log "Waiting for APT lock..."    fi    sleep 5    (( i += 5 ))    if (( i >= 120 )); then      log "WARNING: APT lock still held after 120s — proceeding anyway"      break    fi  done}# -----------------------------------------------------------------------------# Token deb-get# -----------------------------------------------------------------------------TOKEN="${DEBGET_TOKEN:-}"DEBGET_TOKEN_FILE="/etc/deb-get/token"if [[ -z "$TOKEN" && -r "$DEBGET_TOKEN_FILE" ]]; then  TOKEN="$(< "$DEBGET_TOKEN_FILE")"fi# -----------------------------------------------------------------------------# Attente reconstruction cache deb-get# -----------------------------------------------------------------------------debget_wait_cache() {  local cache_dir="/var/cache/deb-get"  local lock_file="${cache_dir}/updating_supported.lock"  local supported_file="${cache_dir}/supported.list"  local supported_apps_file="${cache_dir}/supported_apps.list"  local timeout=120  local elapsed=0  log ">>> Waiting for deb-get supported-app cache"  sleep 1  while (( elapsed < timeout )); do    if [[ ! -e "$lock_file" ]] \      && [[ -s "$supported_file" ]] \      && [[ -s "$supported_apps_file" ]]    then      log "    deb-get cache ready"      return 0    fi    sleep 1    (( elapsed += 1 ))    if (( elapsed % 10 == 0 )); then      log "    Still waiting for deb-get cache (${elapsed}s)"    fi  done  log "WARNING: deb-get cache not confirmed ready after ${timeout}s"  [[ -e "$lock_file" ]] && log "    Lock still present: $lock_file"  [[ ! -s "$supported_file" ]] && log "    Missing/empty: $supported_file"  [[ ! -s "$supported_apps_file" ]] && log "    Missing/empty: $supported_apps_file"  return 1}

fullupdate : mises à jour APT et deb-get

Bannière de démarrage, APT full-upgrade et deb-get avec synchronisation du cache avant la mise à niveau.

BASH
fullupdate.txt · lignes 176–256
# -----------------------------------------------------------------------------# Header# -----------------------------------------------------------------------------CURRENT_KERNEL=$(uname -r)log "================================================================"log "Starting fullupdate v$VERSION"log "Host: $(hostname) | Kernel: $CURRENT_KERNEL"if [[ "$DRYRUN" == "true" ]]; then  log "DRY RUN mode — no changes will be applied"fiif [[ -n "$TOKEN" ]]; then  log "deb-get GitHub token: available"else  log "WARNING: deb-get GitHub token: unavailable"filog "================================================================"# -----------------------------------------------------------------------------# APT# -----------------------------------------------------------------------------log ">>> APT update"apt_wait_lockif [[ "$DRYRUN" == "true" ]]; then  log "[DRYRUN] Would run: apt update && apt full-upgrade"else  apt update  log ">>> APT full-upgrade"  apt full-upgrade -yfi# -----------------------------------------------------------------------------# deb-get# -----------------------------------------------------------------------------if command -v deb-get >/dev/null 2>&1; then  log ">>> deb-get update"  if [[ "$DRYRUN" == "true" ]]; then    log "[DRYRUN] Would run: deb-get update"    log "[DRYRUN] Would wait for deb-get supported-app cache"    log "[DRYRUN] Would run: deb-get upgrade"  else    if [[ -n "$TOKEN" ]]; then      if DEBGET_TOKEN="$TOKEN" deb-get update; then        log "deb-get update completed"      else        log "WARNING: deb-get update failed"      fi    else      if deb-get update; then        log "deb-get update completed"      else        log "WARNING: deb-get update failed"      fi    fi    if debget_wait_cache; then      log ">>> deb-get cache synchronized"    else      log "WARNING: proceeding with deb-get upgrade despite cache wait timeout"    fi    log ">>> deb-get upgrade"    if [[ -n "$TOKEN" ]]; then      DEBGET_TOKEN="$TOKEN" deb-get upgrade \        || log "WARNING: deb-get upgrade failed"    else      deb-get upgrade \        || log "WARNING: deb-get upgrade failed"    fi  fielse  log ">>> deb-get not installed, skipping"fi

fullupdate : Flatpak, Snap, firmware et pipx

Mises à jour Flatpak (système et utilisateur avec environnement XDG explicite), Snap, firmware fwupd et pipx.

BASH
fullupdate.txt · lignes 257–351
# -----------------------------------------------------------------------------# Flatpak (system + user)# -----------------------------------------------------------------------------if command -v flatpak >/dev/null 2>&1; then  log ">>> Flatpak update (system)"  if [[ "$DRYRUN" == "true" ]]; then    log "[DRYRUN] Would run: flatpak update --system -y"  else    flatpak update --system -y \      || log "WARNING: flatpak system update failed"  fi  if [[ -n "${SUDO_USER:-}" ]] \    && [[ "$SUDO_USER" != "root" ]] \    && id "$SUDO_USER" >/dev/null 2>&1  then    USER_HOME="$(getent passwd "$SUDO_USER" | cut -d: -f6)"    if [[ -n "$USER_HOME" && -d "$USER_HOME" ]]; then      USER_XDG_DATA_HOME="${USER_HOME}/.local/share"      USER_XDG_DATA_DIRS="${USER_HOME}/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share"      log ">>> Flatpak update (user: $SUDO_USER)"      if [[ "$DRYRUN" == "true" ]]; then        log "[DRYRUN] Would run Flatpak user update with explicit XDG_DATA_HOME/XDG_DATA_DIRS"      else        sudo -u "$SUDO_USER" \          env \            HOME="$USER_HOME" \            XDG_DATA_HOME="$USER_XDG_DATA_HOME" \            XDG_DATA_DIRS="$USER_XDG_DATA_DIRS" \          flatpak update -y \          || log "WARNING: flatpak user update failed"      fi    else      log "WARNING: unable to determine HOME for user $SUDO_USER; skipping user Flatpak update"    fi  fielse  log ">>> Flatpak not installed, skipping"fi# -----------------------------------------------------------------------------# Snap# -----------------------------------------------------------------------------if command -v snap >/dev/null 2>&1; then  log ">>> Snap refresh"  if [[ "$DRYRUN" == "true" ]]; then    log "[DRYRUN] Would run: snap refresh"  else    snap refresh \      || log "WARNING: snap refresh failed"  fielse  log ">>> Snap not installed, skipping"fi# -----------------------------------------------------------------------------# Firmware (fwupd)# -----------------------------------------------------------------------------if command -v fwupdmgr >/dev/null 2>&1; then  log ">>> fwupd: refreshing metadata"  if [[ "$DRYRUN" == "true" ]]; then    log "[DRYRUN] Would run: fwupdmgr refresh --force && fwupdmgr update"  else    fwupdmgr refresh --force 2>/dev/null \      || log "WARNING: fwupd refresh failed"    fwupdmgr update -y 2>/dev/null \      || log "WARNING: fwupd update failed (no updates or unsupported hardware)"  fielse  log ">>> fwupd not installed, skipping"fi# -----------------------------------------------------------------------------# pipx# -----------------------------------------------------------------------------if command -v pipx >/dev/null 2>&1; then  log ">>> pipx upgrade-all"  if [[ "$DRYRUN" == "true" ]]; then    log "[DRYRUN] Would run: pipx upgrade-all"  else    pipx upgrade-all 2>/dev/null \      || log "WARNING: pipx upgrade-all failed"  fielse  log ">>> pipx not installed, skipping"fi

fullupdate : nettoyage, redémarrage et durée

Nettoyage APT, détection du redémarrage requis avec le noyau le plus récent (tri par version) et durée d’exécution.

BASH
fullupdate.txt · lignes 352–403
# -----------------------------------------------------------------------------# Cleanup APT# -----------------------------------------------------------------------------log ">>> APT autoremove + autoclean"if [[ "$DRYRUN" == "true" ]]; then  log "[DRYRUN] Would run: apt autoremove --purge -y && apt autoclean"else  apt autoremove --purge -y  apt autocleanfi# -----------------------------------------------------------------------------# Reboot detection# -----------------------------------------------------------------------------if [[ -f /run/reboot-required ]]; then  log ">>> REBOOT REQUIRED"  log "    Current kernel: $CURRENT_KERNEL"  if [[ -f /run/reboot-required.pkgs ]]; then    log "    Packages requiring reboot: $(tr '\n' ' ' < /run/reboot-required.pkgs)"  fi  local_new_kernel="$(    ls -1 /boot/vmlinuz-* 2>/dev/null \      | sed 's|/boot/vmlinuz-||' \      | sort -V \      | tail -n1 \      || true  )"  if [[ -n "$local_new_kernel" \     && "$local_new_kernel" != "$CURRENT_KERNEL" ]]  then    log "    New kernel available: $local_new_kernel"  fielse  log ">>> No reboot required"fi# -----------------------------------------------------------------------------# Durée# -----------------------------------------------------------------------------END_TIME=$(date +%s)DURATION=$((END_TIME - START_TIME))log "================================================================"log "fullupdate v$VERSION completed in ${DURATION}s"log "================================================================"echoexit 0

Architecture technique

Langage
Bash
Scripts structurés, strict mode et fonctions réutilisables.
Paquets
APT / dpkg
Inventaire et gestion des paquets noyau.
Boot
GRUB 2
Mise à jour du bootloader et stratégie de retour arrière.
Exploitation
Logs + dry-run
Traçabilité des actions et prévisualisation avant application.

Technologies utilisées

BashLinuxLinux MintRed HatAPTGRUB 2Git