Les boucles : for et while
Notions théoriques
Une boucle permet de répéter automatiquement le même traitement sur plusieurs éléments : plusieurs fichiers, plusieurs utilisateurs, plusieurs serveurs... sans copier-coller le même bloc de code.
La boucle for
for element in valeur1 valeur2 valeur3; do
echo "Élément : $element"
done
À chaque tour, element prend successivement chaque valeur de la liste.
Boucler sur des fichiers avec un motif
for fichier in /var/log/*.log; do
echo "Fichier trouvé : $fichier"
done
Ici, *.log est un motif (glob) que Bash remplace par la liste des fichiers correspondants avant de lancer la boucle.
Entourez toujours "$fichier" de guillemets doubles à l'intérieur de la boucle : un nom de fichier peut contenir un espace, et sans guillemets, Bash le découperait en plusieurs mots.
Boucler sur une plage de nombres
for i in {1..10}; do
echo "Tour numéro $i"
done
# équivalent avec seq, utile quand la plage est calculée dynamiquement
for i in $(seq 1 10); do
echo "Tour numéro $i"
done
Boucler sur les arguments du script
for arg in "$@"; do
echo "Argument : $arg"
done
La boucle while
while répète un bloc **tant qu'**une condition reste vraie :
compteur=1
while [ "$compteur" -le 5 ]; do
echo "Compteur : $compteur"
((compteur++))
done
((compteur++)) est une écriture pratique pour incrémenter une variable numérique.
Lire un fichier ligne par ligne
Un usage très fréquent de while en administration système :
while read -r ligne; do
echo "Ligne lue : $ligne"
done < utilisateurs.txt
Ici, < utilisateurs.txt redirige le contenu du fichier vers l'entrée de la boucle, qui lit une ligne à chaque tour.
Interrompre ou passer un tour
breaksort immédiatement de la boucle.continuepasse directement au tour suivant, sans exécuter le reste du bloc.
for fichier in *.log; do
if [ ! -r "$fichier" ]; then
continue
fi
echo "Traitement de $fichier"
done
Une boucle while dont la condition ne devient jamais fausse tourne indéfiniment (boucle infinie). Si cela vous arrive dans un terminal, Ctrl+C interrompt le script en cours d'exécution.
Vous croiserez aussi until (l'inverse de while : répète tant qu'une condition est fausse) et la syntaxe for ((i=0; i<10; i++)), proche du C. Nous les aborderons au niveau 2.
Exemple pratique
#!/bin/bash
# Script : inventaire_logs.sh
# Rôle : lister les fichiers de log et leur taille
compteur=0
for fichier in /var/log/*.log; do
if [ ! -r "$fichier" ]; then
continue
fi
taille=$(du -h "$fichier" | cut -f1)
echo "$fichier : $taille"
((compteur++))
done
echo "Nombre de fichiers traités : $compteur"
# Lecture ligne par ligne d'une liste d'utilisateurs
while read -r utilisateur; do
echo "Utilisateur à traiter : $utilisateur"
done < utilisateurs.txt
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Nous faisons évoluer sauvegarde.sh pour qu'il puisse traiter plusieurs dossiers en une seule exécution.
Étape 1 — Parcourir tous les arguments du script
Écrivez systématiquement for element in "$@" avec les guillemets. Sans eux, un chemin contenant un espace serait scindé en plusieurs arguments distincts au sein de la boucle.
Étape 2 — Ignorer les dossiers inexistants
Utiliser continue pour écarter un cas particulier en début de boucle rend le code plus lisible que d'imbriquer tout le traitement dans un grand if [ -d "$dossier" ].
Étape 3 — Compter les dossiers traités
Déclarez toujours compteur=0 avant la boucle. Une variable non initialisée peut contenir une valeur inattendue selon ce qui a été exécuté avant dans le script.
Étape 4 — Boucle de confirmation avec while
Avant d'écrire une boucle while, demandez-vous toujours : « qu'est-ce qui va faire que la condition devient un jour fausse ? ». Sans réponse claire, vous risquez une boucle infinie.