Il y a 389 articles et 19 utilisateurs inscrits (ce bandeau est défini dans MediaWiki:Sitenotice)
Script rsync avec copie sur période définies et rapports JSON
- Transfert rsync avec authentification SSH par clé
- Fenêtres horaires :
- Rsync : vendredi 18h → lundi 08h
- Validation hash : lundi 08h01 → vendredi 17h59
- Reprise automatique des fichiers en erreur
- Rapports enrichis JSON + tableau lisible
- Notifications email à plusieurs destinataires
- Compatible Systemd Timer pour planification automatique
Arborescence suggérée
/opt/rsync_sync/
├── config.sh
├── transfert_rsync.sh
├── validation_hash.sh
├── logs/
└── reports/
1️⃣ Fichier de configuration : config.sh
#!/bin/bash
# Configuration générale Rsync + Validation Hash
# --- Connexion SSH ---
RSYNC_USER="user"
RSYNC_HOST="serveurA"
RSYNC_SSH_OPTS="-i ~/.ssh/rsync_key -p 22"
# --- Répertoire unique de destination sur B ---
DST="/chemin/destination_sur_B/"
# --- Répertoires sources sur A ---
DIRS_TO_COPY=("/var/data" "/var/data2")
# --- Options Rsync ---
RSYNC_OPTS="-avz --partial --progress --bwlimit=50000 --human-readable --stats"
# --- Répertoires de logs et rapports ---
LOG_DIR="/opt/rsync_sync/logs"
REPORT_DIR="/opt/rsync_sync/reports"
mkdir -p "$LOG_DIR" "$REPORT_DIR"
# --- Fichiers de suivi ---
ERROR_FILE="$LOG_DIR/errors.txt"
HASH_FILE="$LOG_DIR/rsync_hashes_$(date +%F).txt"
# --- Notification email ---
EMAIL_TO=("admin1@example.com" "admin2@example.com")
EMAIL_SUBJECT_PREFIX="[SYNC SERVEUR A → B]"
# --- Outil d'envoi d'e-mail ---
MAIL_CMD="mail" # ou 'sendmail' selon ton environnement
2️⃣ Script transfert rsync : transfert_rsync.sh
#!/bin/bash
# ===============================================
# TRANSFERT RSYNC SERVEUR A → SERVEUR B
# Objectif :
# - Transférer les fichiers sources depuis A vers B
# - Gérer la reprise automatique des erreurs
# - Générer des rapports JSON + tableau clair
# - Notifier par e-mail les résultats
# ===============================================
source /opt/rsync_sync/config.sh
DATE_TAG=$(date +%F_%H-%M)
LOG_FILE="$LOG_DIR/rsync_transfer_$DATE_TAG.log"
JSON_REPORT="$REPORT_DIR/rsync_report_$DATE_TAG.json"
TABLE_REPORT="$REPORT_DIR/rsync_summary_$DATE_TAG.txt"
echo "==== DÉBUT TRANSFERT $(date) ====" >> "$LOG_FILE"
# --------------------------
# Initialisation des compteurs
# --------------------------
declare -A STATS=(["sources"]=0 ["transferred"]=0 ["errors"]=0 ["retried"]=0)
ERROR_DETAILS="$LOG_DIR/rsync_errors_$DATE_TAG.txt"
> "$ERROR_DETAILS"
# --------------------------
# Boucle sur les répertoires à transférer
# --------------------------
for src_dir in "${DIRS_TO_COPY[@]}"; do
((STATS["sources"]++))
echo "[INFO] Transfert de $src_dir → $DST" >> "$LOG_FILE"
# 1️⃣ Reprise des erreurs précédentes
if [ -s "$ERROR_FILE" ]; then
echo "[INFO] Reprise des erreurs précédentes listées dans $ERROR_FILE" >> "$LOG_FILE"
rsync_output=$(rsync $RSYNC_OPTS -e "ssh $RSYNC_SSH_OPTS" --files-from="$ERROR_FILE" \
"$RSYNC_USER@$RSYNC_HOST:$src_dir/" "$DST" 2>&1)
echo "$rsync_output" >> "$LOG_FILE"
retried_count=$(echo "$rsync_output" | grep -c '^>')
STATS["retried"]=$((STATS["retried"] + retried_count))
> "$ERROR_FILE"
fi
# 2️⃣ Transfert principal
echo "[INFO] Lancement transfert principal depuis $src_dir" >> "$LOG_FILE"
rsync_output=$(rsync $RSYNC_OPTS -e "ssh $RSYNC_SSH_OPTS" \
"$RSYNC_USER@$RSYNC_HOST:$src_dir/" "$DST" 2>&1)
echo "$rsync_output" >> "$LOG_FILE"
transferred_count=$(echo "$rsync_output" | grep -c '^>')
error_count=$(echo "$rsync_output" | grep -c 'rsync error')
STATS["transferred"]=$((STATS["transferred"] + transferred_count))
STATS["errors"]=$((STATS["errors"] + error_count))
# 3️⃣ Liste des fichiers transférés pour la validation future
ssh $RSYNC_SSH_OPTS "$RSYNC_USER@$RSYNC_HOST" "find $src_dir -type f" >> "$HASH_FILE"
# 4️⃣ Log et rapport des erreurs
if [ "$error_count" -gt 0 ]; then
echo "[ERREUR] $error_count erreurs détectées sur $src_dir" >> "$ERROR_DETAILS"
fi
done
echo "==== FIN TRANSFERT $(date) ====" >> "$LOG_FILE"
# --------------------------
# Génération du rapport JSON
# --------------------------
cat > "$JSON_REPORT" <<EOF
{
"date": "$(date)",
"sources": "${DIRS_TO_COPY[*]}",
"destination": "$DST",
"stats": {
"sources_count": ${STATS["sources"]},
"files_transferred": ${STATS["transferred"]},
"files_retried": ${STATS["retried"]},
"errors": ${STATS["errors"]}
},
"log_file": "$LOG_FILE",
"error_details": "$ERROR_DETAILS"
}
EOF
# --------------------------
# Génération du tableau lisible
# --------------------------
cat > "$TABLE_REPORT" <<EOF
===========================
RAPPORT DE TRANSFERT RSYNC
===========================
Date : $(date)
Sources : ${DIRS_TO_COPY[*]}
Destination : $DST
--------------------------------
Répertoires traités : ${STATS["sources"]}
Fichiers transférés : ${STATS["transferred"]}
Reprises d'erreurs : ${STATS["retried"]}
Erreurs détectées : ${STATS["errors"]}
--------------------------------
Logs détaillés : $LOG_FILE
Rapport JSON : $JSON_REPORT
--------------------------------
EOF
# --------------------------
# Rapport résumé clair dans les logs
# --------------------------
{
echo "RÉSUMÉ DU TRANSFERT"
echo "---------------------"
echo "Répertoires traités : ${STATS["sources"]}"
echo "Fichiers transférés : ${STATS["transferred"]}"
echo "Reprises effectuées : ${STATS["retried"]}"
echo "Erreurs détectées : ${STATS["errors"]}"
echo "---------------------"
} >> "$LOG_FILE"
# --------------------------
# Notifications email
# --------------------------
if [ "${#EMAIL_TO[@]}" -gt 0 ]; then
for mail in "${EMAIL_TO[@]}"; do
{
echo -e "Sujet : $EMAIL_SUBJECT_PREFIX Transfert Rsync - $(date)"
echo
cat "$TABLE_REPORT"
if [ "${STATS["errors"]}" -gt 0 ]; then
echo
echo "⚠️ Des erreurs Rsync ont été détectées. Voir :"
echo " $ERROR_DETAILS"
fi
} | $MAIL_CMD -s "$EMAIL_SUBJECT_PREFIX Transfert Rsync - $(date)" "$mail"
done
fi
exit 0
3️⃣ Script validation hash : validation_hash.sh
#!/bin/bash
# ===============================================
# VALIDATION HASH SERVEUR A → SERVEUR B
# Objectif :
# - Vérifier l’intégrité des fichiers transférés
# - Identifier les erreurs de hash ou fichiers manquants
# - Générer un rapport JSON + tableau clair
# - Envoyer notifications email multi-destinataires
# ===============================================
source /opt/rsync_sync/config.sh
DATE_TAG=$(date +%F_%H-%M)
LOG_FILE="$LOG_DIR/validation_$DATE_TAG.log"
JSON_REPORT="$REPORT_DIR/validation_report_$DATE_TAG.json"
TABLE_REPORT="$REPORT_DIR/validation_summary_$DATE_TAG.txt"
echo "==== DÉBUT VALIDATION HASH $(date) ====" >> "$LOG_FILE"
# --------------------------
# Initialisation des compteurs
# --------------------------
declare -A HASH_STATS=(["checked"]=0 ["ok"]=0 ["errors"]=0 ["missing"]=0)
ERROR_DETAILS="$LOG_DIR/validation_errors_$DATE_TAG.txt"
> "$ERROR_DETAILS"
# --------------------------
# Boucle de validation
# --------------------------
while read -r file; do
# Calcul du hash source distant
src_hash=$(ssh $RSYNC_SSH_OPTS "$RSYNC_USER@$RSYNC_HOST" "sha256sum '$file' 2>/dev/null" | awk '{print $1}')
dest_file="$DST/$(basename "$file")"
if [ -f "$dest_file" ]; then
dest_hash=$(sha256sum "$dest_file" | awk '{print $1}')
if [ "$src_hash" == "$dest_hash" ] && [ -n "$src_hash" ]; then
((HASH_STATS["ok"]++))
else
((HASH_STATS["errors"]++))
echo "$file" >> "$ERROR_FILE"
echo "[HASH ERROR] $file" >> "$LOG_FILE"
echo "[HASH ERROR] $file" >> "$ERROR_DETAILS"
fi
else
((HASH_STATS["missing"]++))
echo "$file" >> "$ERROR_FILE"
echo "[MISSING] $file" >> "$LOG_FILE"
echo "[MISSING] $file" >> "$ERROR_DETAILS"
fi
((HASH_STATS["checked"]++))
done < "$HASH_FILE"
echo "==== FIN VALIDATION HASH $(date) ====" >> "$LOG_FILE"
# --------------------------
# Génération du rapport JSON
# --------------------------
cat > "$JSON_REPORT" <<EOF
{
"date": "$(date)",
"stats": {
"files_checked": ${HASH_STATS["checked"]},
"hash_ok": ${HASH_STATS["ok"]},
"hash_errors": ${HASH_STATS["errors"]},
"missing_files": ${HASH_STATS["missing"]}
},
"log_file": "$LOG_FILE",
"errors_file": "$ERROR_DETAILS",
"error_list_file": "$ERROR_FILE"
}
EOF
# --------------------------
# Génération du tableau lisible
# --------------------------
cat > "$TABLE_REPORT" <<EOF
==============================
VALIDATION HASH - SYNTHÈSE
==============================
Date : $(date)
--------------------------------
Fichiers vérifiés : ${HASH_STATS["checked"]}
Conformes (hash OK) : ${HASH_STATS["ok"]}
Erreurs de hash : ${HASH_STATS["errors"]}
Fichiers manquants : ${HASH_STATS["missing"]}
--------------------------------
Logs détaillés : $LOG_FILE
Erreurs détaillées : $ERROR_DETAILS
Rapport JSON : $JSON_REPORT
--------------------------------
EOF
# --------------------------
# Rapport résumé clair dans les logs
# --------------------------
{
echo "RÉSUMÉ VALIDATION HASH"
echo "------------------------"
echo "Total vérifiés : ${HASH_STATS["checked"]}"
echo "OK : ${HASH_STATS["ok"]}"
echo "Erreurs : ${HASH_STATS["errors"]}"
echo "Manquants : ${HASH_STATS["missing"]}"
echo "------------------------"
} >> "$LOG_FILE"
# --------------------------
# Notifications email
# --------------------------
if [ "${#EMAIL_TO[@]}" -gt 0 ]; then
for mail in "${EMAIL_TO[@]}"; do
{
echo -e "Sujet : $EMAIL_SUBJECT_PREFIX Validation Hash - $(date)"
echo
cat "$TABLE_REPORT"
if [ "${HASH_STATS["errors"]}" -gt 0 ] || [ "${HASH_STATS["missing"]}" -gt 0 ]; then
echo
echo "⚠️ Des erreurs ont été détectées. Voir détails dans :"
echo " $ERROR_DETAILS"
fi
} | $MAIL_CMD -s "$EMAIL_SUBJECT_PREFIX Validation Hash - $(date)" "$mail"
done
fi
exit 0
4️⃣ Workflow visuel avec fenêtres horaires
Vendredi 18h Lundi 08h01 Vendredi 17h59
+-----------------------------+---------------------------+
| | |
| TRANSFERT RSYNC | VALIDATION HASH |
| (reprise erreurs + copie) | (fichiers copiés) |
| | |
+-----------------------------+---------------------------+
Cycle :
- Les fichiers en erreur sont ajoutés à errors.txt
- Week-end suivant, rsync reprend les erreurs en priorité
- Transfert incrémental pour nouveaux fichiers
- Validation hash continue en semaine
Ordonnancement
5️⃣ Systemd Services et Timers
a) Service rsync : /etc/systemd/system/rsync_sync.service
[Unit]
Description=Transfert Rsync serveur A → B
After=network.target
[Service]
Type=oneshot
ExecStart=/opt/rsync_sync/transfert_rsync.sh
User=root
b) Timer rsync : /etc/systemd/system/rsync_sync.timer
[Unit]
Description=Planification Transfert Rsync (Ven 18h → Lun 08h)
[Timer]
# Début vendredi 18h
OnCalendar=Fri 18:00
# Persistant pour lancer le transfert même si l'heure est passée
Persistent=true
[Install]
WantedBy=timers.target
c) Service validation hash : /etc/systemd/system/validation_hash.service
[Unit]
Description=Validation Hash serveur A → B
After=network.target
[Service]
Type=oneshot
ExecStart=/opt/rsync_sync/validation_hash.sh
User=root
d) Timer validation hash : /etc/systemd/system/validation_hash.timer
[Unit]
Description=Planification Validation Hash (Lun 08h01 → Ven 17h59)
[Timer]
# Début lundi 08h01
OnCalendar=Mon 08:01
Persistent=true
[Install]
WantedBy=timers.target
e) Activer les timers
sudo systemctl daemon-reload
sudo systemctl enable --now rsync_transfer.timer
sudo systemctl enable --now rsync_validation.timer
Crontab
1️⃣ Planification rsync via cron (vendredi 18h → lundi 08h)
- Ouvrir le crontab pour l’utilisateur qui exécute le script :
crontab -e - Ajouter la ligne suivante pour lancer le transfert vendredi 18h :0 18 * * 5 → vendredi à 18h00
0 18 * * 5 /opt/rsync_sync/transfert_rsync.sh
- Ajouter une ligne optionnelle pour assurer le démarrage lundi 08h (au cas où le transfert serait interrompu ou pour reprise) :0 8 * * 1 → lundi 08h00
0 8 * * 1 /opt/rsync_sync/transfert_rsync.sh
Les scripts incluent déjà un contrôle de fin de fenêtre (RSYNC_END) pour arrêter le transfert lundi 08h00.
2️⃣ Planification validation hash via cron (lundi 08h01 → vendredi 17h59)
- Toujours dans le crontab :Lancement lundi 08h01
1 8 * * 1 /opt/rsync_sync/validation_hash.sh
- Optionnel : relancer la validation toutes les heures pendant la semaine, pour traiter les fichiers par lots si nécessaire :De 9h à 17h du lundi au vendredi, toutes les heures. Le script s’arrête automatiquement si la fenêtre VALIDATION_END (vendredi 17h59) est dépassée
0 9-17 * * 1-5 /opt/rsync_sync/validation_hash.sh
3️⃣ Avantages de cette version cron
Compatible tous serveurs Linux/Unix
- Même logique que Systemd :
- Reprise automatique des erreurs
- Fenêtres horaires respectées
- Rapports JSON + tableau lisible
- Notifications email
Facile à tester sans redémarrer le daemon systemd