Lezione 23 – Progetti pratici: creare uno script utile

⏱️ Tempo stimato: 12 min

🧩 Difficoltà: Avanzato

🌟 Obiettivi specifici

  1. Progettare uno script Bash avanzato per backup differenziale.
  2. Utilizzare opzioni, logging, locking e notifica via email.
  3. Integrare buona struttura e sicurezza nello script.

📖 Sezione teorica

Nella realizzazione di uno script backup differenziale Bash, entreremo immediatamente nel vivo della progettazione e della buona pratica.

Progettazione

  • Definizione delle directory origine, destinazione e file di stato.
  • Opzioni: -s per sorgente, -t per target, -e per escludere pattern, -n dry‑run.

Logging e locking

  • exec 3>>"$LOGFILE" e gestione errori trap.
  • File lock per evitare esecuzioni concorrenti: flock -n.

Backup differenziale

  • Uso di rsync con --link-dest= per hard link.
  • Timestamp della destinazione.

Notifica email

  • Comando mailx o sendmail con PID, stato e allegato log.

Best practice

  • Codice robusto con set -euo pipefail.
  • Chiarezza variabili ed error handling.
  • Documentazione del codice.

🔶 Esempi pratici

Codice completo

#!/usr/bin/env bash
# backup_diff.sh – script avanzato backup differenziale

set -euo pipefail
IFS=$'\n\t'

usage() {
  cat <<EOF
Uso: $0 -s ORIGINE -t DESTINAZIONE [-e PATTERN ...] [-n]
  -s origine (dir da salvare)
  -t destinazione (backup root)
  -e pattern da escludere (ripetibile)
  -n dry-run
EOF
  exit 1
}

ORIGINE="" DEST="" DRY=0
EXCLUDE=()
while getopts "s:t:e:n" opt; do
  case $opt in
    s) ORIGINE=$OPTARG ;;
    t) DEST=$OPTARG ;;
    e) EXCLUDE+=("$OPTARG") ;;
    n) DRY=1 ;;
    *) usage ;;
  esac
done
[[ -z $ORIGINE || -z $DEST ]] && usage

mkdir -p "$DEST"
LOGFILE="$DEST/backup_$(date +%Y%m%d_%H%M%S).log"
exec 3>>"$LOGFILE"

echo "[$(date)] Avvio backup" >&3

LOCKFILE="/var/lock/backup_diff.lock"
exec 200>"$LOCKFILE"
flock -n 200 || { echo "Un'istanza è già in esecuzione"; exit 1; }

LAST=$(ls -1dt "$DEST"/backup_* | head -n1 || :)
DEST_NOW="$DEST/backup_$(date +%Y%m%d_%H%M%S)"

RSYNC_OPTS=(-a --delete)
for pat in "${EXCLUDE[@]}"; do
  RSYNC_OPTS+=(--exclude="$pat")
done
if [[ $DRY -eq 1 ]]; then
  RSYNC_OPTS+=(--dry-run)
fi
if [[ -n $LAST ]]; then
  RSYNC_OPTS+=(--link-dest="$LAST")
fi

echo "Esecuzione rsync..." >&3
rsync "${RSYNC_OPTS[@]}" "$ORIGINE/" "$DEST_NOW/" >&3 2>&1

echo "[$(date)] Backup completato" >&3

echo "Backup $(basename "$DEST_NOW") completato con successo" | mailx -s "Backup eseguito" -a "$LOGFILE" [email protected]

echo "🔷 Lezione 23 completata" >&3

Spiegazione dettagliata:

  • set -euo pipefail + IFS → robustezza su variabili, errori, pipe.
  • getopts → parsing opzioni.
  • Logging su file .log.
  • Locking su /var/lock.
  • rsync differenziale con --link-dest.
  • Notifica via mailx, allega log.

📝 Esercizio finale

Adatta lo script per includere:

  • invio report mensile cumulativo via cron.
  • compressione del backup (tar.gz), mantenendo solo gli ultimi 7 giorni.
  • filtro opzionale per file modificati > X giorni (passare parametro -m X).

🧠 Quiz a scelta multipla

  1. Quale opzione rsync consente di creare collegamenti invece di copiare?
    ✅ B) --link-dest
  2. Quale comando previene esecuzioni concorrenti dello script?
    ✅ A) flock -n
  3. Perché set -euo pipefail è utile?
    ✅ B) Blocca variabili unset ed errori improvvisi

❓ FAQ aggiuntive

1. Posso usare mail anziché mailx?
Sì, basta adattare i parametri -s, -a.

2. Cosa succede se rsync non trova file modificati?
Crea comunque la struttura vuota: per evitare archivi vuoti, controlla la presenza di file nel backup.

3. Dove impostare lo script nel crontab?
Esempio:

0 2 * * * /usr/local/bin/backup_diff.sh -s /home/user -t /mnt/backup -e '*.tmp'

✅ Checklist finale

  • #!/usr/bin/env bash + set -euo pipefail, IFS=
  • getopts con opzioni -s, -t, -e, -n
  • Logging su file .log con fd 3
  • Locking con flock
  • rsync con --link-dest, --dry-run, --exclude, --delete
  • Notifica email con allegato log
  • Messaggio "🔷 Lezione 23 completata" nel log

🔀 Collegamento alla lezione successiva

Prosegui con Lezione 24 – Conclusioni e test finale
Vai alla Lezione 24



📩 Vuoi il PDF della lezione? Scrivici!
🔗 Prosegui alla prossima lezione
💬 Hai dubbi? Lascia un commento!

Lascia un commento