Écrire des scripts Bash pour automatiser les tâches récurrentes : sauvegarde, monitoring, déploiement.
#!/bin/bash) en première ligne indique à Linux d'utiliser Bash pour interpréter le script.
Voici votre premier script. Il affiche des informations sur le système. Chaque ligne est commentée pour que vous compreniez exactement ce qui se passe :
#!/bin/bash
# ↑ Shebang : cette ligne OBLIGATOIRE en 1ère position dit à Linux
# d'utiliser Bash pour exécuter ce script
# mon-premier-script.sh
# Description : Affiche des informations utiles sur le système
echo "=== Informations Système ==="
# $(commande) exécute une commande et insère le résultat dans le texte
echo "Hostname : $(hostname)" # Nom de la machine
# lsb_release affiche la version de l'OS. Le 2>/dev/null masque les erreurs
# si la commande n'existe pas, on utilise une alternative avec /etc/os-release
echo "OS : $(lsb_release -ds 2>/dev/null || cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2)"
echo "Kernel : $(uname -r)" # Version du noyau Linux
echo "Uptime : $(uptime -p)" # Depuis combien de temps le serveur tourne
echo "IP : $(hostname -I | awk '{print $1}')" # Adresse IP principale
echo "Disk Usage :"
# df -h = espace disque en format lisible (Go, Mo)
# tail -1 = on prend la dernière ligne (le disque principal /)
# awk formate la sortie pour n'afficher que ce qui nous intéresse
df -h / | tail -1 | awk '{printf " Used: %s / %s (%s)\n", $3, $2, $5}'
echo "RAM Usage :"
# free -h = mémoire RAM en format lisible
# grep Mem = on filtre la ligne "Mem" (mémoire physique)
free -h | grep Mem | awk '{printf " Used: %s / %s\n", $3, $2}'
Pour le rendre exécutable et le lancer :
# chmod +x rend le fichier exécutable (droit d'exécution)
# Sans cette commande, Linux refusera de lancer le script
chmod +x mon-premier-script.sh
# ./ signifie "dans le dossier courant". On lance le script !
./mon-premier-script.sh
Ce script crée une archive compressée d'un dossier avec la date dans le nom, et supprime les anciennes sauvegardes automatiquement. C'est le script le plus utile en production :
#!/bin/bash
# backup.sh — Sauvegarde un dossier avec rotation automatique
# ─── VARIABLES DE CONFIGURATION ───
# Modifiez ces valeurs selon vos besoins
SOURCE="/var/www/html" # Le dossier à sauvegarder
DEST="/backup" # Où stocker les sauvegardes
DATE=$(date +%Y-%m-%d_%H%M%S) # Date actuelle au format 2026-03-28_143022
ARCHIVE="backup_${DATE}.tar.gz" # Nom du fichier archive (unique grâce à la date)
RETENTION=7 # Nombre de jours de conservation (les plus vieilles seront supprimées)
# ─── CRÉATION DU DOSSIER DE DESTINATION ───
# mkdir -p : crée le dossier ET ses parents si nécessaire, sans erreur si déjà existant
mkdir -p "$DEST"
# ─── CRÉATION DE L'ARCHIVE ───
echo "[$(date)] Début de la sauvegarde..."
# tar = outil d'archivage Linux
# -c = create (créer une archive)
# -z = gzip (compresser l'archive pour réduire sa taille)
# -f = file (spécifier le nom du fichier de sortie)
# -C = changer de répertoire avant d'archiver (pour éviter les chemins absolus dans l'archive)
tar -czf "${DEST}/${ARCHIVE}" -C "$(dirname "$SOURCE")" "$(basename "$SOURCE")"
# ─── VÉRIFICATION DU RÉSULTAT ───
# $? contient le code de retour de la dernière commande (0 = succès, autre = erreur)
if [ $? -eq 0 ]; then
echo "[$(date)] Sauvegarde réussie : ${ARCHIVE}"
# du -h = affiche la taille du fichier en format lisible (Mo, Go)
SIZE=$(du -h "${DEST}/${ARCHIVE}" | cut -f1)
echo "[$(date)] Taille : ${SIZE}"
else
echo "[$(date)] ERREUR : La sauvegarde a échoué !" >&2 # >&2 envoie vers stderr (erreur)
exit 1 # Quitter le script avec un code d'erreur
fi
# ─── ROTATION : SUPPRESSION DES ANCIENNES SAUVEGARDES ───
echo "[$(date)] Nettoyage des sauvegardes de plus de ${RETENTION} jours..."
# find cherche les fichiers correspondant au pattern
# -mtime +7 = modifié il y a plus de 7 jours
# -delete = les supprime
find "$DEST" -name "backup_*.tar.gz" -mtime +${RETENTION} -delete
echo "[$(date)] Terminé."
Un script qui vérifie l'état des services et envoie une alerte :
#!/bin/bash
# monitor.sh — Vérifie les services et l'espace disque
# Ce script est conçu pour tourner toutes les 5 minutes via cron
# Fichier où seront écrits les résultats
LOG="/var/log/monitor.log"
# Seuil d'alerte pour le disque (en pourcentage)
DISK_THRESHOLD=80
# Fonction "log" : affiche un message avec la date ET l'écrit dans le fichier log
# tee -a = écrit à la fois à l'écran et à la fin du fichier (-a = append)
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"
}
# --- Vérification des services ---
# On définit la liste des services à surveiller dans un tableau
SERVICES=("ssh" "nginx" "docker")
# Boucle : pour chaque service dans la liste...
for svc in "${SERVICES[@]}"; do
# systemctl is-active vérifie si le service tourne
# --quiet = pas de sortie texte, juste le code retour
# 2>/dev/null = masque les erreurs si le service n'existe pas
if systemctl is-active --quiet "$svc" 2>/dev/null; then
log "OK : $svc est actif"
else
log "ALERTE : $svc est DOWN !"
fi
done
# --- Vérification de l'espace disque ---
# df / = espace disque de la partition racine
# awk '{print $5}' = récupère la 5ème colonne (pourcentage)
# tr -d '%' = enlève le symbole % pour pouvoir comparer les chiffres
DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
# -gt = "greater than" (supérieur à)
if [ "$DISK_USAGE" -gt "$DISK_THRESHOLD" ]; then
log "ALERTE : Disque à ${DISK_USAGE}% (seuil: ${DISK_THRESHOLD}%)"
else
log "OK : Disque à ${DISK_USAGE}%"
fi
# --- Vérification de la RAM ---
# free = affiche l'utilisation mémoire
# $3/$2 = mémoire utilisée / mémoire totale (en pourcentage)
RAM_USED=$(free | grep Mem | awk '{printf "%.0f", $3/$2 * 100}')
log "INFO : RAM utilisée à ${RAM_USED}%"
#!/bin/bash
# Quand vous lancez un script avec des arguments (ex: ./script.sh hello world)
# ces arguments sont accessibles via des variables spéciales :
echo "Script : $0" # $0 = le nom du script lui-même
echo "Argument 1 : $1" # $1 = le 1er argument passé ("hello")
echo "Nombre d'arguments : $#" # $# = combien d'arguments au total
# Créer ses propres variables (pas d'espace autour du =)
NOM="serveur-web"
PORT=8080
# ${} permet d'insérer une variable dans du texte
echo "Déploiement de ${NOM} sur le port ${PORT}"
#!/bin/bash
FILE="/etc/nginx/nginx.conf"
# [ -f "$FILE" ] vérifie si le fichier existe (-f = file)
# [ -d "/chemin" ] vérifie si le dossier existe (-d = directory)
if [ -f "$FILE" ]; then
echo "Nginx est installé, configuration trouvée."
elif [ -d "/etc/apache2" ]; then
echo "Apache est installé à la place."
else
echo "Aucun serveur web détecté."
fi
#!/bin/bash
# Définit un tableau (array) de serveurs à tester
SERVERS=("web01" "web02" "db01" "db02")
# ${SERVERS[@]} = tous les éléments du tableau
for srv in "${SERVERS[@]}"; do
echo "Ping de ${srv}..."
# ping -c 1 = envoie 1 seul ping, -W 2 = timeout de 2 secondes
# &>/dev/null = masque toute la sortie (on veut juste le résultat)
# && = si le ping réussit, || = sinon
ping -c 1 -W 2 "$srv" &>/dev/null && echo " → $srv OK" || echo " → $srv DOWN"
done
#!/bin/bash
# deploy.sh — Déploie une application web depuis un dépôt Git
# Usage : ./deploy.sh https://github.com/user/mon-site.git
REPO_URL="$1" # Le 1er argument = l'URL du dépôt Git
DEPLOY_DIR="/var/www/html" # Dossier où le site est hébergé
BACKUP_DIR="/backup/deploy" # Dossier pour les sauvegardes avant déploiement
DATE=$(date +%Y%m%d_%H%M%S) # Date actuelle pour nommer les fichiers
# Vérifie qu'on a bien fourni l'URL en argument
# -z = "zero length" (la variable est vide)
if [ -z "$REPO_URL" ]; then
echo "Usage: $0 <url-du-repo-git>" >&2 # >&2 = affiche sur stderr (erreur)
exit 1 # Quitte avec un code d'erreur
fi
# Étape 1 : Sauvegarde de la version actuelle (au cas où)
echo "→ Sauvegarde de la version actuelle..."
mkdir -p "$BACKUP_DIR"
# tar crée une archive compressée du site actuel
tar -czf "${BACKUP_DIR}/pre-deploy_${DATE}.tar.gz" -C "$DEPLOY_DIR" .
# Étape 2 : Mise à jour du code depuis Git
echo "→ Déploiement depuis ${REPO_URL}..."
cd "$DEPLOY_DIR" || exit 1 # Se placer dans le dossier (ou quitter si impossible)
# Vérifie si c'est déjà un dépôt Git (dossier .git présent)
if [ -d ".git" ]; then
git pull origin main # Oui → on met à jour le code existant
else
rm -rf "$DEPLOY_DIR"/* # Non → on nettoie et on clone le dépôt
git clone "$REPO_URL" "$DEPLOY_DIR"
fi
# Étape 3 : Redémarrer le serveur web pour prendre en compte les changements
echo "→ Redémarrage de Nginx..."
sudo systemctl reload nginx # reload = recharge la config sans couper les connexions
echo "→ Déploiement terminé avec succès !"
chmod +x deploy.sh
./deploy.sh https://github.com/user/mon-site.git
#!/bin/bash (shebang)set -euo pipefail pour arrêter le script en cas d'erreur"$VARIABLE"bash -x script.sh pour le mode debug#!/bin/bash
# Active le mode "strict" pour éviter les erreurs silencieuses
set -euo pipefail
# -e : arrête le script dès qu'une commande échoue (au lieu de continuer)
# -u : arrête si on utilise une variable non définie (faute de frappe !)
# -o pipefail : détecte les erreurs dans les pipes (cmd1 | cmd2)
# Mode debug (décommenter pour voir chaque commande avant son exécution)
# set -x