|
1 | | -#!/bin/bash |
| 1 | +#!/usr/bin/env bash |
| 2 | +# new.sh — version verbose pour techniciens |
2 | 3 |
|
3 | | -########################################## INITIALISATION ROOT ########################################## |
| 4 | +################################################################################ |
| 5 | +# Options opérateur |
| 6 | +# --debug : active bash -x et logs DEBUG |
| 7 | +# --dry-run : n'exécute rien (affiche uniquement) |
| 8 | +# --quiet : réduit la verbosité à WARN/ERROR |
| 9 | +################################################################################ |
4 | 10 |
|
5 | | -# Vérifier si l'utilisateur est root |
| 11 | +set -euo pipefail |
| 12 | + |
| 13 | +# ============================== CLI Flags ====================================== |
| 14 | +DEBUG=0 |
| 15 | +DRYRUN=0 |
| 16 | +QUIET=0 |
| 17 | +for arg in "$@"; do |
| 18 | + case "${arg:-}" in |
| 19 | + --debug) DEBUG=1 ;; |
| 20 | + --dry-run|--dryrun) DRYRUN=1 ;; |
| 21 | + --quiet|-q) QUIET=1 ;; |
| 22 | + *) ;; |
| 23 | + esac |
| 24 | +done |
| 25 | +[[ $DEBUG -eq 1 ]] && set -x |
| 26 | + |
| 27 | +# ============================== Logging ======================================== |
| 28 | +_start_ts=$(date +%s) |
| 29 | +LOG_TS="$(date +%Y%m%d-%H%M%S)" |
| 30 | +LOG_DIR="/var/log" |
| 31 | +LOG_FILE="${LOG_DIR}/new.sh-${LOG_TS}.log" |
| 32 | +mkdir -p "$LOG_DIR" |
| 33 | +# Redirige TOUT vers tee (stdout + fichier) |
| 34 | +exec > >(tee -a "$LOG_FILE") 2>&1 |
| 35 | + |
| 36 | +# Couleurs |
| 37 | +BOLD="\e[1m"; DIM="\e[2m"; RED="\e[31m"; YEL="\e[33m"; GRN="\e[32m"; BLU="\e[34m"; C0="\e[0m" |
| 38 | + |
| 39 | +_now() { date "+%Y-%m-%d %H:%M:%S%z"; } |
| 40 | +_since() { local s=$1; printf "%ds" $(( $(date +%s) - s )); } |
| 41 | + |
| 42 | +log() { printf "%b[%s] [INFO ]%b %s\n" "$GRN" "$(_now)" "$C0" "$*"; } |
| 43 | +warn() { printf "%b[%s] [WARN ]%b %s\n" "$YEL" "$(_now)" "$C0" "$*"; } |
| 44 | +err() { printf "%b[%s] [ERROR]%b %s\n" "$RED" "$(_now)" "$C0" "$*"; } |
| 45 | +debug() { [[ $DEBUG -eq 1 ]] && printf "%b[%s] [DEBUG]%b %s\n" "$BLU" "$(_now)" "$C0" "$*"; } |
| 46 | +logq() { [[ $QUIET -eq 0 ]] && log "$@" || true; } |
| 47 | + |
| 48 | +# Affiche et exécute une commande (ou simule en dry-run) |
| 49 | +run() { |
| 50 | + local desc="$1"; shift |
| 51 | + local ts=$(date +%s) |
| 52 | + if [[ $DRYRUN -eq 1 ]]; then |
| 53 | + printf "%b[%s] [DRYRN]%b %s → %s\n" "$DIM" "$(_now)" "$C0" "$desc" "$*" |
| 54 | + return 0 |
| 55 | + fi |
| 56 | + printf "%b[%s] [EXEC ]%b %s\n" "$BOLD" "$(_now)" "$C0" "$desc" |
| 57 | + debug "Commande: $*" |
| 58 | + if "$@"; then |
| 59 | + log "OK: $desc (durée $(_since "$ts"))" |
| 60 | + return 0 |
| 61 | + else |
| 62 | + err "ECHEC: $desc (durée $(_since "$ts"))" |
| 63 | + return 1 |
| 64 | + fi |
| 65 | +} |
| 66 | + |
| 67 | +# ============================== Root & contexte ================================ |
6 | 68 | if [[ $EUID -ne 0 ]]; then |
7 | | - echo "Ce script doit être exécuté en tant que root" |
8 | | - # Demander le mot de passe |
9 | | - sudo "$0" "$@" |
10 | | - exit 1 |
| 69 | + warn "Ce script doit être exécuté en root. Tentative avec sudo…" |
| 70 | + exec sudo -E "$0" "$@" |
| 71 | +fi |
| 72 | + |
| 73 | +trap 'err "Interruption ou erreur (code=$?) — voir $LOG_FILE"; exit 1' INT TERM |
| 74 | + |
| 75 | +log "Journal complet: $LOG_FILE" |
| 76 | +log "Hôte: $(hostname) | Kernel: $(uname -r) | Arch: $(uname -m)" |
| 77 | +log "Shell: $SHELL | DEBUG=$DEBUG | DRYRUN=$DRYRUN | QUIET=$QUIET" |
| 78 | + |
| 79 | +# ============================== Détection distro =============================== |
| 80 | +DIST_ID=""; DIST_LIKE="" |
| 81 | +if [[ -r /etc/os-release ]]; then |
| 82 | + # shellcheck disable=SC1091 |
| 83 | + . /etc/os-release |
| 84 | + DIST_ID="${ID:-unknown}" |
| 85 | + DIST_LIKE="${ID_LIKE:-}" |
| 86 | +else |
| 87 | + err "/etc/os-release introuvable — abandon." |
| 88 | + exit 1 |
11 | 89 | fi |
| 90 | +log "Distribution détectée: ID=${DIST_ID} | ID_LIKE=${DIST_LIKE}" |
| 91 | + |
| 92 | +# ============================== Gestionnaire paquets =========================== |
| 93 | +PKG_MGR="" PKG_UPDATE="" PKG_UPGRADE="" PKG_INSTALL="" PKG_QUERY="" |
| 94 | +case "$DIST_ID" in |
| 95 | + debian|ubuntu|linuxmint|pop) |
| 96 | + export DEBIAN_FRONTEND=noninteractive |
| 97 | + PKG_MGR="apt" |
| 98 | + PKG_UPDATE="apt-get update -y" |
| 99 | + PKG_UPGRADE="apt-get -y full-upgrade --autoremove --purge" |
| 100 | + PKG_INSTALL="apt-get install -y" |
| 101 | + PKG_QUERY="apt-cache policy" |
| 102 | + ;; |
| 103 | + fedora) |
| 104 | + PKG_MGR="dnf" |
| 105 | + PKG_UPDATE="dnf -y makecache" |
| 106 | + PKG_UPGRADE="dnf -y upgrade --refresh" |
| 107 | + PKG_INSTALL="dnf -y install" |
| 108 | + PKG_QUERY="dnf info" |
| 109 | + ;; |
| 110 | + rhel|centos|rocky|almalinux) |
| 111 | + if command -v dnf >/dev/null 2>&1; then |
| 112 | + PKG_MGR="dnf"; PKG_UPDATE="dnf -y makecache"; PKG_UPGRADE="dnf -y upgrade --refresh"; PKG_INSTALL="dnf -y install"; PKG_QUERY="dnf info" |
| 113 | + else |
| 114 | + PKG_MGR="yum"; PKG_UPDATE="yum -y makecache"; PKG_UPGRADE="yum -y update"; PKG_INSTALL="yum -y install"; PKG_QUERY="yum info" |
| 115 | + fi |
| 116 | + ;; |
| 117 | + arch|artix|manjaro) |
| 118 | + PKG_MGR="pacman" |
| 119 | + PKG_UPDATE="pacman -Sy --noconfirm" |
| 120 | + PKG_UPGRADE="pacman -Syu --noconfirm" |
| 121 | + PKG_INSTALL="pacman -S --noconfirm --needed" |
| 122 | + PKG_QUERY="pacman -Si" |
| 123 | + ;; |
| 124 | + opensuse*|sles) |
| 125 | + PKG_MGR="zypper" |
| 126 | + PKG_UPDATE="zypper --non-interactive refresh" |
| 127 | + PKG_UPGRADE="zypper --non-interactive update" |
| 128 | + PKG_INSTALL="zypper --non-interactive install --no-confirm" |
| 129 | + PKG_QUERY="zypper info" |
| 130 | + ;; |
| 131 | + alpine) |
| 132 | + PKG_MGR="apk" |
| 133 | + PKG_UPDATE="apk update" |
| 134 | + PKG_UPGRADE="apk upgrade" |
| 135 | + PKG_INSTALL="apk add --no-cache" |
| 136 | + PKG_QUERY="apk info -e" |
| 137 | + ;; |
| 138 | + *) |
| 139 | + case "$DIST_LIKE" in |
| 140 | + *debian*) DIST_ID="debian"; export DEBIAN_FRONTEND=noninteractive |
| 141 | + PKG_MGR="apt"; PKG_UPDATE="apt-get update -y"; PKG_UPGRADE="apt-get -y full-upgrade --autoremove --purge"; PKG_INSTALL="apt-get install -y"; PKG_QUERY="apt-cache policy" ;; |
| 142 | + *rhel*|*fedora*) DIST_ID="rhel" |
| 143 | + if command -v dnf >/dev/null 2>&1; then |
| 144 | + PKG_MGR="dnf"; PKG_UPDATE="dnf -y makecache"; PKG_UPGRADE="dnf -y upgrade --refresh"; PKG_INSTALL="dnf -y install"; PKG_QUERY="dnf info" |
| 145 | + else |
| 146 | + PKG_MGR="yum"; PKG_UPDATE="yum -y makecache"; PKG_UPGRADE="yum -y update"; PKG_INSTALL="yum -y install"; PKG_QUERY="yum info" |
| 147 | + fi ;; |
| 148 | + *) |
| 149 | + err "Distribution non gérée (ID=$DIST_ID ID_LIKE=$DIST_LIKE)"; exit 1 ;; |
| 150 | + esac |
| 151 | + ;; |
| 152 | +esac |
| 153 | +log "Gestionnaire de paquets: $PKG_MGR" |
| 154 | +debug "CMD update='$PKG_UPDATE' upgrade='$PKG_UPGRADE' install='$PKG_INSTALL' query='$PKG_QUERY'" |
12 | 155 |
|
13 | | -# Le reste du script ici |
| 156 | +# ============================== Helpers paquets ================================ |
| 157 | +pkg_available() { |
| 158 | + local pkg="$1" |
| 159 | + case "$PKG_MGR" in |
| 160 | + apt) $PKG_QUERY "$pkg" >/dev/null 2>&1 ;; |
| 161 | + dnf|yum) $PKG_QUERY "$pkg" >/dev/null 2>&1 ;; |
| 162 | + pacman) $PKG_QUERY "$pkg" >/dev/null 2>&1 ;; |
| 163 | + zypper) $PKG_QUERY "$pkg" >/dev/null 2>&1 ;; |
| 164 | + apk) $PKG_QUERY "$pkg" >/dev/null 2>&1 ;; |
| 165 | + *) return 1 ;; |
| 166 | + esac |
| 167 | +} |
14 | 168 |
|
15 | | -#################################################### FIN #################################################### |
| 169 | +install_if_exists() { |
| 170 | + local group="$1"; shift |
| 171 | + local wanted=("$@") |
| 172 | + local ok=() skip=() |
| 173 | + for p in "${wanted[@]}"; do |
| 174 | + if pkg_available "$p"; then ok+=("$p"); else skip+=("$p"); fi |
| 175 | + done |
| 176 | + if ((${#ok[@]})); then |
| 177 | + logq "Installation ($group): ${ok[*]}" |
| 178 | + if [[ $DRYRUN -eq 0 ]]; then |
| 179 | + # shellcheck disable=SC2086 |
| 180 | + run "Installer ($group)" $PKG_INSTALL ${ok[*]} || warn "Erreur installation ($group)" |
| 181 | + else |
| 182 | + printf "[DRYRUN] %s %s\n" "$PKG_INSTALL" "${ok[*]}" |
| 183 | + fi |
| 184 | + else |
| 185 | + warn "Aucun paquet installable pour le lot: $group" |
| 186 | + fi |
| 187 | + if ((${#skip[@]})); then |
| 188 | + warn "Indisponibles ($group): ${skip[*]}" |
| 189 | + fi |
| 190 | +} |
16 | 191 |
|
17 | | -apt update -y && apt full-upgrade --autoremove --purge -y |
| 192 | +# ============================== MAJ système =================================== |
| 193 | +ts_update=$(date +%s) |
| 194 | +run "MAJ index paquets" bash -c "$PKG_UPDATE" || warn "Update partielle/échouée" |
| 195 | +run "Upgrade système" bash -c "$PKG_UPGRADE" || warn "Upgrade partielle/échouée" |
| 196 | +log "Section MAJ terminée (durée $(_since "$ts_update"))" |
18 | 197 |
|
19 | | -apt install gnupg{,2} lm-sensors curl wget htop nload screen vim git ncdu bpytop rsync man avahi-daemon tree dnsutils net-tools ripgrep -y |
| 198 | +# ============================== Mapping paquets =============================== |
| 199 | +# Paquets communs (mappés selon distro) |
| 200 | +PKG_GNUPG=(gnupg gnupg2) # apt gère les deux; autres distros n'installeront que celui dispo |
| 201 | +PKG_LMSENS=(lm-sensors) |
| 202 | +PKG_COMMON=(curl wget htop nload screen vim git ncdu rsync tree net-tools ripgrep) |
| 203 | +PKG_MAN_DEB=(man-db) |
| 204 | +PKG_DNS_DEB=(dnsutils) |
| 205 | +PKG_DNS_RPM=(bind-utils) |
| 206 | +PKG_DNS_ARCH_ALP=(bind-tools) |
| 207 | +PKG_AVAHI_DEB=(avahi-daemon) |
| 208 | +PKG_AVAHI_OTH=(avahi) # Arch/RPM/openSUSE/Alpine |
| 209 | +PKG_BPY=(bpytop) |
| 210 | +PKG_BTOP=(btop) |
20 | 211 |
|
21 | | -# Installation de 'fastfetch' (remplacement de 'neofetch') |
22 | | -echo "Installation du paquet FastFetch" |
23 | | -bash <(curl -s https://raw.githubusercontent.com/OverStyleFR/AutoScriptBash/main/.assets/fastfetch-install.sh) |
| 212 | +log "Sélection des paquets selon famille: $DIST_ID ($PKG_MGR)" |
24 | 213 |
|
25 | | -# Mettre l'heure de Europe/Paris |
26 | | -sudo timedatectl set-timezone Europe/Paris |
| 214 | +case "$PKG_MGR" in |
| 215 | + apt) |
| 216 | + install_if_exists "gnupg" "${PKG_GNUPG[@]}" |
| 217 | + install_if_exists "lm-sensors" "${PKG_LMSENS[@]}" |
| 218 | + install_if_exists "commun" "${PKG_COMMON[@]}" "${PKG_MAN_DEB[@]}" "${PKG_DNS_DEB[@]}" "${PKG_AVAHI_DEB[@]}" |
| 219 | + # bpytop ou btop |
| 220 | + if pkg_available "${PKG_BPY[0]}"; then install_if_exists "monitoring" "${PKG_BPY[@]}"; else install_if_exists "monitoring" "${PKG_BTOP[@]}"; fi |
| 221 | + ;; |
| 222 | + dnf|yum) |
| 223 | + install_if_exists "gnupg" gnupg |
| 224 | + install_if_exists "lm-sensors" "${PKG_LMSENS[@]}" |
| 225 | + install_if_exists "commun" "${PKG_COMMON[@]}" "${PKG_DNS_RPM[@]}" "${PKG_AVAHI_OTH[@]}" |
| 226 | + if pkg_available "${PKG_BPY[0]}"; then install_if_exists "monitoring" "${PKG_BPY[@]}"; else install_if_exists "monitoring" "${PKG_BTOP[@]}"; fi |
| 227 | + ;; |
| 228 | + pacman) |
| 229 | + install_if_exists "gnupg" gnupg |
| 230 | + install_if_exists "lm-sensors" lm_sensors |
| 231 | + install_if_exists "commun" "${PKG_COMMON[@]}" "${PKG_DNS_ARCH_ALP[@]}" "${PKG_AVAHI_OTH[@]}" |
| 232 | + if pkg_available "${PKG_BPY[0]}"; then install_if_exists "monitoring" "${PKG_BPY[@]}"; else install_if_exists "monitoring" "${PKG_BTOP[@]}"; fi |
| 233 | + ;; |
| 234 | + zypper) |
| 235 | + install_if_exists "gnupg" gpg2 |
| 236 | + install_if_exists "lm-sensors" "${PKG_LMSENS[@]}" |
| 237 | + install_if_exists "commun" "${PKG_COMMON[@]}" "${PKG_DNS_RPM[@]}" "${PKG_AVAHI_OTH[@]}" |
| 238 | + if pkg_available "${PKG_BPY[0]}"; then install_if_exists "monitoring" "${PKG_BPY[@]}"; else install_if_exists "monitoring" "${PKG_BTOP[@]}"; fi |
| 239 | + ;; |
| 240 | + apk) |
| 241 | + install_if_exists "gnupg" gnupg |
| 242 | + install_if_exists "lm-sensors" lm-sensors |
| 243 | + install_if_exists "commun" "${PKG_COMMON[@]}" "${PKG_DNS_ARCH_ALP[@]}" "${PKG_AVAHI_OTH[@]}" |
| 244 | + if pkg_available "${PKG_BPY[0]}"; then install_if_exists "monitoring" "${PKG_BPY[@]}"; else install_if_exists "monitoring" "${PKG_BTOP[@]}"; fi |
| 245 | + ;; |
| 246 | +esac |
| 247 | + |
| 248 | +# ============================== Fastfetch (repo > fallback) ==================== |
| 249 | +install_fastfetch() { |
| 250 | + local ts=$(date +%s) |
| 251 | + if pkg_available fastfetch; then |
| 252 | + log "fastfetch disponible dans les dépôts: installation via $PKG_MGR" |
| 253 | + install_if_exists "fastfetch" fastfetch |
| 254 | + log "fastfetch installé via dépôts (durée $(_since "$ts"))" |
| 255 | + return 0 |
| 256 | + fi |
| 257 | + warn "fastfetch non dispo dans les dépôts — fallback script externe" |
| 258 | + local URL="https://raw.githubusercontent.com/OverStyleFR/AutoScriptBash/main/.assets/fastfetch-install.sh" |
| 259 | + if [[ $DRYRUN -eq 1 ]]; then |
| 260 | + printf "[DRYRUN] bash <(curl -fsSL %s)\n" "$URL" |
| 261 | + return 0 |
| 262 | + fi |
| 263 | + if command -v curl >/dev/null 2>&1; then |
| 264 | + run "Installer fastfetch (script)" bash -c "bash <(curl -fsSL \"$URL\")" |
| 265 | + elif command -v wget >/dev/null 2>&1; then |
| 266 | + run "Installer fastfetch (script)" bash -c "bash <(wget -qO- \"$URL\")" |
| 267 | + else |
| 268 | + err "Ni curl ni wget disponibles — fastfetch non installé." |
| 269 | + return 1 |
| 270 | + fi |
| 271 | + log "fastfetch via script terminé (durée $(_since "$ts"))" |
| 272 | +} |
| 273 | +install_fastfetch || warn "Installation fastfetch échouée (script)." |
| 274 | + |
| 275 | +# ============================== Timezone ====================================== |
| 276 | +if command -v timedatectl >/dev/null 2>&1; then |
| 277 | + run "Réglage timezone Europe/Paris" timedatectl set-timezone Europe/Paris || warn "Echec réglage timezone" |
| 278 | +else |
| 279 | + warn "timedatectl indisponible — saut du réglage timezone." |
| 280 | +fi |
| 281 | + |
| 282 | +# ============================== Cron @reboot =================================== |
| 283 | +if command -v crontab >/dev/null 2>&1; then |
| 284 | + log "Ajout cron @reboot (ping court vers 1.1.1.1)" |
| 285 | + if [[ $DRYRUN -eq 0 ]]; then |
| 286 | + (crontab -l 2>/dev/null | grep -v "ping -c 5 1\.1\.1\.1" 2>/dev/null; echo '@reboot /bin/ping -c 5 1.1.1.1 >/dev/null 2>&1 || true') | crontab - |
| 287 | + else |
| 288 | + echo "[DRYRUN] crontab append: @reboot /bin/ping -c 5 1.1.1.1 >/dev/null 2>&1 || true" |
| 289 | + fi |
| 290 | +else |
| 291 | + warn "crontab indisponible (cron non installé ?)" |
| 292 | +fi |
| 293 | + |
| 294 | +# ============================== .bashrc perso ================================= |
| 295 | +BRC_URL="https://raw.githubusercontent.com/OverStyleFR/AutoScriptBash/main/.assets/.bashrc" |
| 296 | +if [[ -f "$HOME/.bashrc" ]]; then |
| 297 | + run "Backup ~/.bashrc" cp -a "$HOME/.bashrc" "$HOME/.bashrc.bak.$(date +%Y%m%d-%H%M%S)" || true |
| 298 | +fi |
| 299 | +if command -v curl >/dev/null 2>&1; then |
| 300 | + [[ $DRYRUN -eq 1 ]] && echo "[DRYRUN] curl -fsSL $BRC_URL -o $HOME/.bashrc" || run "Télécharger .bashrc" curl -fsSL "$BRC_URL" -o "$HOME/.bashrc" |
| 301 | +elif command -v wget >/dev/null 2>&1; then |
| 302 | + [[ $DRYRUN -eq 1 ]] && echo "[DRYRUN] wget -q $BRC_URL -O $HOME/.bashrc" || run "Télécharger .bashrc" wget -q "$BRC_URL" -O "$HOME/.bashrc" |
| 303 | +else |
| 304 | + warn "Ni curl ni wget pour récupérer le .bashrc" |
| 305 | +fi |
| 306 | + |
| 307 | +# Recharge seulement en shell interactif bash |
| 308 | +if [[ -n "${PS1:-}" && -n "${BASH_VERSION:-}" && $DRYRUN -eq 0 ]]; then |
| 309 | + # shellcheck disable=SC1090 |
| 310 | + run "Recharger ~/.bashrc" bash -lc "source \"$HOME/.bashrc\"" || true |
| 311 | +fi |
| 312 | + |
| 313 | +# ============================== Avahi ========================================= |
| 314 | +if command -v systemctl >/dev/null 2>&1; then |
| 315 | + if systemctl list-unit-files | grep -q '^avahi-daemon\.service'; then |
| 316 | + run "Activer avahi-daemon" systemctl enable --now avahi-daemon || warn "Impossible d'activer avahi-daemon" |
| 317 | + else |
| 318 | + debug "Service avahi-daemon non présent — ignoré." |
| 319 | + fi |
| 320 | +else |
| 321 | + debug "systemctl indisponible — probablement sans systemd." |
| 322 | +fi |
27 | 323 |
|
28 | | -# Initialisation IP # |
29 | | -(crontab -l ; echo "@reboot /bin/ping -c 5 1.1") | crontab - |
| 324 | +# ============================== Récapitulatif ================================= |
| 325 | +echo |
| 326 | +echo -e "${BOLD}============================= RÉCAPITULATIF =============================${C0}" |
| 327 | +echo " - Journal complet : $LOG_FILE" |
| 328 | +echo " - Distro : ID=$DIST_ID | LIKE=$DIST_LIKE | PKG_MGR=$PKG_MGR" |
| 329 | +echo " - DEBUG : $DEBUG | DRYRUN=$DRYRUN | QUIET=$QUIET" |
| 330 | +echo " - Durée totale : $(_since "$_start_ts")" |
| 331 | +echo -e "${BOLD}=========================================================================${C0}" |
30 | 332 |
|
31 | | -cd |
32 | | -rm .bashrc |
33 | | -curl -O https://raw.githubusercontent.com/OverStyleFR/AutoScriptBash/main/.assets/.bashrc |
34 | | -source .bashrc |
| 333 | +log "Configuration terminée." |
35 | 334 |
|
| 335 | +# Fin |
0 commit comments