Variables, conditions et boucles en shell
Automatiser des tâches répétitives, c'est le coeur du métier de technicien système. Un script shell, c'est simplement une suite de commandes dans un fichier texte que l'on exécute en une fois. Vous connaissez déjà les commandes individuelles : les variables, conditions et boucles vous permettent de les rendre intelligentes.
La structure d'un script
#!/bin/bash
# Ce commentaire explique le but du script
# Auteur : Alice - Date : 2026-01-15
echo "Démarrage du script"
La première ligne #!/bin/bash s'appelle le shebang : elle indique quel interpréteur utiliser. Rendez le script exécutable avec chmod +x script.sh avant de le lancer avec ./script.sh.
Variables
# Déclaration (pas d'espace autour du =)
NOM="srv-glpi"
PORT=443
DOSSIER="/var/log/glpi"
# Utilisation ($ devant le nom)
echo "Serveur : $NOM sur le port $PORT"
echo "Logs dans : ${DOSSIER}/php-errors.log"
# Variables spéciales
echo $0 # nom du script
echo $1 # premier argument passé au script
echo $# # nombre d'arguments
echo $? # code de retour de la dernière commande (0 = succès)
Conditions if/elif/else
#!/bin/bash
SERVICE="apache2"
# Tester si un service tourne
if systemctl is-active --quiet $SERVICE; then
echo "$SERVICE est actif"
elif systemctl is-enabled --quiet $SERVICE; then
echo "$SERVICE est installé mais arrêté"
else
echo "$SERVICE n'est pas installé"
fi
# Tester si un fichier existe
if [ -f "/etc/glpi/config_db.php" ]; then
echo "Config GLPI trouvée"
else
echo "ERREUR : config GLPI manquante"
exit 1 # quitter le script avec code d'erreur
fi
# Comparaisons numériques
ESPACE=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
if [ $ESPACE -gt 90 ]; then
echo "ALERTE : disque à $ESPACE%"
fi
Opérateurs de test fichier : -f (fichier), -d (dossier), -e (existe), -r (lisible), -z (variable vide)
Boucles for
# Boucle sur une liste
for SERVEUR in srv-glpi srv-ad srv-backup; do
echo "Ping $SERVEUR..."
ping -c 1 $SERVEUR > /dev/null && echo "OK" || echo "HORS LIGNE"
done
# Boucle sur des fichiers
for LOG in /var/log/glpi/*.log; do
echo "Taille de $LOG : $(du -sh $LOG | cut -f1)"
done
# Boucle numérique
for i in $(seq 1 5); do
echo "Tentative $i..."
done
Boucles while
# Attendre qu'un service démarre
COMPTEUR=0
while ! systemctl is-active --quiet apache2; do
echo "Attente démarrage Apache... ($COMPTEUR s)"
sleep 2
COMPTEUR=$((COMPTEUR + 2))
if [ $COMPTEUR -gt 60 ]; then
echo "Timeout : Apache n'a pas démarré"
exit 1
fi
done
echo "Apache est démarré !"
Cas concret
Script de vérification quotidienne des serveurs PME :
#!/bin/bash
# check-serveurs.sh : Vérifie la disponibilité des serveurs
RAPPORT="/var/log/check-serveurs-$(date +%Y%m%d).log"
echo "=== Vérification $(date) ===" > $RAPPORT
check_host() {
IP=$1
NOM=$2
if ping -c 1 -W 2 $IP > /dev/null 2>&1; then
echo "OK $NOM ($IP)" | tee -a $RAPPORT
else
echo "FAIL $NOM ($IP) : HORS LIGNE" | tee -a $RAPPORT
fi
}
check_host "192.168.1.10" "srv-glpi"
check_host "192.168.1.20" "srv-ad"
check_host "192.168.1.30" "srv-backup"
echo "Rapport : $RAPPORT"
flowchart TD
START([Début du script]) --> READ[Lire liste serveurs]
READ --> LOOP{Pour chaque serveur}
LOOP --> PING[ping -c 1 serveur]
PING --> OK{Code retour = 0 ?}
OK -->|Oui| LOG_OK["Écrire 'OK' dans rapport"]
OK -->|Non| LOG_FAIL["Écrire 'FAIL' dans rapport"]
LOG_OK --> NEXT[Serveur suivant]
LOG_FAIL --> NEXT
NEXT --> LOOP
LOOP -->|Tous testés| END([Fin : afficher rapport])
Erreurs fréquentes
- Mettre des espaces autour du
=dans une assignation :NOM = "srv"est une erreur (bash cherche une commande "NOM"). La bonne syntaxe :NOM="srv". - Oublier les guillemets autour de
$VARIABLEdans les tests : si la variable est vide,[ $VAR -gt 0 ]devient[ -gt 0 ]qui cause une erreur. - Confondre
=(assignation) et==(comparaison dans[[ ]]) : dans[ ], utilisez=pour comparer des chaînes.
À retenir
- Le shebang
#!/bin/bashest obligatoire en première ligne. $?contient le code de retour de la dernière commande : 0 = succès, autre = erreur.- Toujours tester un script avec
bash -n script.sh(dry-run syntax check) avant de l'exécuter.
Mini-exercice
Créez un script /tmp/espace.sh qui affiche un avertissement si le disque / est utilisé à plus de 80%. Utilisez df / | tail -1 | awk '{print $5}' | tr -d '%' pour obtenir le pourcentage. Rendez-le exécutable et testez-le.