⏱️ Tempo stimato: 12 min
🧩 Difficoltà: Avanzato
🌟 Obiettivi specifici
- Progettare uno script Bash avanzato per backup differenziale.
- Utilizzare opzioni, logging, locking e notifica via email.
- 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:
-sper sorgente,-tper target,-eper escludere pattern,-ndry‑run.
Logging e locking
exec 3>>"$LOGFILE"e gestione erroritrap.- File lock per evitare esecuzioni concorrenti:
flock -n.
Backup differenziale
- Uso di
rsynccon--link-dest=per hard link. - Timestamp della destinazione.
Notifica email
- Comando
mailxosendmailcon 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. rsyncdifferenziale 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
- Quale opzione
rsyncconsente di creare collegamenti invece di copiare?
✅ B)--link-dest - Quale comando previene esecuzioni concorrenti dello script?
✅ A)flock -n - 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=getoptscon opzioni-s,-t,-e,-n- Logging su file
.logcon fd 3 - Locking con
flock rsynccon--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
Link interno:
- Lezione 12 – Introduzione a rsync per backup incrementali
Link esterno - Documentazione ufficiale di rsync – esempio con –link-dest
📩 Vuoi il PDF della lezione? Scrivici!
🔗 Prosegui alla prossima lezione
💬 Hai dubbi? Lascia un commento!
