Les boucles for constituent l’un des piliers fondamentaux de l’automatisation en Bash, permettant aux administrateurs et développeurs de traiter efficacement des tâches répétitives sans intervention manuelle. Maîtriser cette construction de contrôle de flux offre la capacité d’exécuter des commandes shell complexes sur des listes d’éléments, des fichiers ou des plages numériques, transformant ainsi des processus fastidieux en scripts optimisés et maintenables.

🎯 Comment structurer une boucle for en Bash pour démarrer efficacement
La structure d’une boucle for en Bash s’appuie sur deux syntaxes principales : la première parcourt une liste d’éléments avec for variable in liste ; la seconde, de style C, utilise for ((initialisation; condition; incrément)). Les deux syntaxes permettent d’automatiser des tâches répétitives.
La boucle for en Bash se décline selon deux syntaxes distinctes, chacune adaptée à des contextes spécifiques. La première approche, fondée sur l’itération directe, parcourt l’ensemble des éléments d’une liste et s’apparente à un modèle ForEach. Elle offre une lisibilité immédiate et fonctionne avec n’importe quel type de collection : mots, nombres, fichiers ou résultats de commandes shell.
La forme basique se présente ainsi :
for <variable> in <liste>
do
# Instructions à exécuter
done
La deuxième syntaxe emprunte les conventions du langage C, utilisant trois expressions qui délimitent l’état initial, la condition de répétition et l’incrément. Cette variante offre un contrôle granulaire sur le déroulement de la boucle for et s’avère particulièrement utile lors de manipulations numériques précises.
for (( condition initiale; condition de répétition; incrément ))
do
# Instructions à exécuter
done
La différence fondamentale entre ces deux approches réside dans la flexibilité offerte : la première brille dans l’itération sur des collections hétérogènes, tandis que la seconde excelle dans les boucles gouvernées par des variables numériques. Comprendre cette distinction permet de sélectionner l’outil idéal selon le contexte d’automatisation envisagé.
📋 Les deux syntaxes principales à maîtriser
La première syntaxe, dite ForEach, fonctionne en extrayant séquentiellement chaque élément d’une liste et en l’assignant à une variable temporaire. Cette variable, définie au sein de la déclaration for, reste accessible durant l’exécution de chaque itération. Lorsque la boucle atteint l’instruction done, elle passe à l’élément suivant jusqu’à l’épuisement de la liste.
La syntaxe C-style, en revanche, fonctionne sur la base de trois compartiments entre parenthèses. Le premier initialise une variable (généralement un compteur), le second définit la condition de poursuite, et le troisième spécifie l’opération à effectuer après chaque itération. Cette approche ressemble aux constructions for des langages comme le C, le Java ou Python.
Pour illustrer concrètement, une boucle basique sur une énumération numérique produit des résultats identiques quelle que soit la syntaxe choisie. Voici un exemple utilisant la première approche :
#!/bin/bash
for i in 1 2 3 4 5
do
echo « Étape numéro $i »
done
L’alternative avec syntaxe C-style s’écrit :
#!/bin/bash
for (( i=1; i<=5; i++ ))
do
echo « Étape numéro $i »
done
Les deux versions retournent le même résultat : l’affichage des nombres 1 à 5. Cependant, dans la première syntaxe, on peut remplacer l’énumération « 1 2 3 4 5 » par {1..5} pour générer automatiquement la séquence, ce qui allège considérablement le code lorsqu’on manipule de grandes plages numériques.
La syntaxe for ((…)) en Bash permet d’effectuer des incréments personnalisés : vous pouvez augmenter de 2, 3 ou tout autre pas, par exemple for ((i=0; i<=10; i+=2)).
🔧 Automatiser le traitement de fichiers avec des boucles for
Pour automatiser le traitement de fichiers en Bash, utilisez une boucle for combinée à des motifs de fichiers (.extension) ou à la commande find, ce qui permet d’itérer sur chaque fichier correspondant et d’exécuter des opérations comme la lecture, le comptage de lignes ou la modification.
L’une des applications les plus puissantes des boucles for en Bash consiste à traiter automatiquement des collections de fichiers présents dans des répertoires. Cette capacité transforme des opérations manuelles répétitives en processus scriptés, rapides et fiables. Un cas d’usage classique implique l’analyse des fichiers d’un dossier pour en extraire des informations structurées.
Considérez un scénario où un administrateur système doit vérifier le nombre de lignes contenues dans chaque fichier texte d’un dossier donné. Sans boucle for, cette tâche exigerait d’exécuter la commande wc pour chaque fichier individuellement. Avec une boucle, l’ensemble du processus s’automatise en quelques lignes :
#!/bin/bash
for fichier in /home/utilisateur/Documents/*.txt
do
echo « $fichier : $(cat $fichier | wc -l) ligne(s) »
done
Ce script itère sur chaque fichier .txt du répertoire cible et affiche son chemin accompagné du nombre de lignes. La substitution de commande $(cat $fichier | wc -l) exécute le comptage pour chaque fichier et insère le résultat directement dans la chaîne d’affichage.
💾 Parcourir les fichiers d’un répertoire avec des jokers
Le recours aux motifs de jokers (wildcards) comme *.txt ou *.log offre une flexibilité remarquable. Ces motifs permettent de capturer automatiquement tous les fichiers correspondant à un critère sans devoir les énumérer explicitement. Bash expanse ces motifs en une liste complète avant que la boucle n’entreprenne ses itérations.
Supposons qu’une entreprise dispose d’un dossier contenant des fichiers de configuration avec l’extension .conf. Une boucle for dotée du motif *.conf traitera chaque fichier de configuration indépendamment, permettant la validation, la transformation ou l’archivage de ces éléments en une seule exécution scriptée.
Un autre scénario pratique consiste à filtrer les fichiers selon leur modification récente. Bien que la boucle for elle-même ne dispose pas de filtre temporel natif, on peut combiner la boucle avec des commandes comme find pour obtenir un résultat raffiné :
#!/bin/bash
for fichier in $(find /home/utilisateur/Documents -name « *.txt » -mtime -7)
do
echo « Fichier modifié récemment : $fichier »
done
Cette approche récupère uniquement les fichiers texte modifiés au cours des sept derniers jours, limitant ainsi le champ de traitement. La substitution de commande agit comme passerelle entre find et la boucle for, transformant la sortie énumérée en liste directement itérable.
🔄 Extraction et manipulation de noms de fichiers
Lors du traitement de fichiers, extraire ou modifier les noms constitue une opération fréquente. Bash offre plusieurs mécanismes pour manipuler les chaînes de caractères représentant les noms de fichiers. L’expansion de variable ${variable//ancien/nouveau} permet de remplacer des occurrences au sein du nom, facilitant les renommages en masse ou les nettoyages de nomenclature.
Imaginez des fichiers contenant des espaces dans leurs noms, source fréquente de dysfonctionnements dans les scripts shell. Une boucle for combinée à l’expansion de variable peut standardiser automatiquement la nomenclature :
#!/bin/bash
for fichier in *.txt
do
mv « $fichier » « ${fichier// /_} »
done
Ce script remplace chaque espace par un tiret bas dans les noms des fichiers texte du répertoire courant. Ici, // signale le remplacement de toutes les occurrences (par opposition à / qui ne remplacerait que la première). Cette technique s’avère indispensable pour normaliser les données ou préparer les fichiers en vue d’un traitement ultérieur par des outils sensibles aux espaces.
Pour éviter les problèmes avec les fichiers contenant des espaces ou des caractères spéciaux, privilégiez les boucles utilisant find … -print0 combiné à while read -d » pour une robustesse maximale.

✏️ Renommer des fichiers en masse avec une boucle for
Renommer des fichiers en masse s’effectue avec une boucle for parcourant chaque fichier ciblé puis en utilisant la commande mv pour appliquer des préfixes, suffixes ou remplacer des caractères, ce qui automatise et sécurise les opérations de renommage répétitives.
Le renommage en masse de fichiers représente un cas d’usage extrêmement courant en administration système et en gestion de contenu numérique. Là où une approche manuelle exigerait des dizaines de clics ou des commandes répétées, une boucle for effectue l’ensemble des modifications en secondes, tout en éliminant les risques d’erreur humaine.
Une nécessité fréquente consiste à ajouter un préfixe standardisé à une collection de fichiers. Cela facilite l’organisation, la traçabilité ou l’intégration dans des pipelines de traitement. Voici comment procéder :
#!/bin/bash
for fichier in *.txt
do
mv « $fichier » « archive_$fichier »
done
Une exécution de ce script dans un dossier contenant document1.txt, document2.txt et document3.txt produira archive_document1.txt, archive_document2.txt et archive_document3.txt. Cette approche garantit la cohérence nomenclaturale et facilite l’identification ultérieure des fichiers traités selon une certaine période ou un certain processus.
🔤 Remplacer des caractères dans les noms de fichiers
Au-delà de l’ajout de préfixes, la substitution de caractères constitue une opération souvent requise. Certains environnements ou applications interdisent ou découragent l’usage de caractères spéciaux dans les noms de fichiers. Une boucle for dotée de l’expansion de variable bash offre une solution élégante et efficace.
Prenez l’exemple d’une collection de fichiers contenant des caractères de soulignement qui doivent être convertis en tirets pour des raisons de compatibilité. L’expansion ${variable//ancien/nouveau} remplace toutes les occurrences :
#!/bin/bash
for fichier in *.txt
do
mv « $fichier » « ${fichier//_/-} »
done
Le mécanisme fonctionne de la manière suivante : la variable fichier contient le nom d’origine, // indique le remplacement complet, _ représente le caractère à chercher, et – constitue le caractère de remplacement. Ainsi, un fichier nommé rapport_mensuel_2026.txt devient rapport-mensuel-2026.txt.
Pour des transformations plus complexes impliquant plusieurs remplacements successifs, on peut imbriquer plusieurs expansions ou exécuter plusieurs commandes mv consécutives au sein de la même itération :
#!/bin/bash
for fichier in *.txt
do
nouveau= »${fichier//[[:space:]]/_} »
nouveau= »${nouveau//-/.} »
mv « $fichier » « $nouveau »
done
Cette variante remplace d’abord tous les espaces par des tirets bas, puis convertit tous les tirets en points, offrant une chaîne de transformations orchestrées au sein d’une même boucle.
🎯 Automatiser le renommage selon des conditions
Certains scénarios imposent des renommages conditionnels : ne renommer que les fichiers dépassant une taille donnée, modifier seulement ceux datant d’avant une certaine période, ou appliquer des suffixes différents selon l’extension. Combiner la boucle for avec des structures conditionnelles if/else amplifie considérablement les capacités de la programmation en Bash.
Voici un exemple renommant uniquement les fichiers texte volumineux en ajoutant le suffixe « large » :
#!/bin/bash
for fichier in *.txt
do
taille=$(stat -f%z « $fichier »)
if [ $taille -gt 1000000 ]; then
mv « $fichier » « ${fichier%.txt}_large.txt »
fi
done
Ici, la commande stat extrait la taille du fichier en octets, et la condition if vérifie si elle dépasse un million d’octets. Seuls les fichiers répondant à ce critère subissent le renommage, les autres demeurant inchangés. Cette approche combine puissamment l’itération, la conditionnelle et la manipulation de chaînes.
En combinant les commandes find et for, vous pouvez cibler très précisément les fichiers à traiter selon leur date, leur taille ou toute autre caractéristique avancée.
⚙️ Gérer les services système avec des boucles for
Gérer les services système via une boucle for permet d’automatiser des tâches comme le redémarrage, l’arrêt ou la vérification de l’état de plusieurs services d’un système Linux, en utilisant systemctl de façon itérative sur une liste prédéfinie de services.
Pour les administrateurs système, la capacité à automatiser la gestion de services constitue un gain de productivité considérable. Au lieu de redémarrer manuellement chaque service ou de vérifier leur statut individuellement, une boucle for orchestrée par la commande shell systemctl effectue ces opérations en quelques secondes, tout en générant des rapports détaillés.
Imaginons un administrateur chargé de redémarrer cinq services critiques après une mise à jour système. Exécuter manuellement chaque commande de redémarrage introduirait des délais et des risques d’oubli. Une approche scriptée élimine ces frictions :
#!/bin/bash
services=(« ssh » « apache2 » « mysql » « nginx » « postfix »)
for service in ${services[@]}
do
echo « Redémarrage du service : $service »
systemctl restart $service
done
Ce script déclare un tableau contenant les noms des services, puis itère sur chaque élément via la syntaxe ${services[@]}. La boucle for exécute le redémarrage pour chaque service, avec un message de confirmation pour chaque étape. Notez que l’exécution requiert les privilèges élevés (sudo), car la gestion des services ne s’autorise que pour l’administrateur système.
🔍 Vérifier l’état des services en masse
Aussi important que de redémarrer les services, monitorer leur statut opérationnel revêt une importance capitale. Au lieu de parcourir une dizaine de services manuellement, une boucle for couplée à systemctl extrait rapidement le statut global :
#!/bin/bash
services=(« ssh » « apache2 » « mysql » « nginx » « postfix »)
for service in ${services[@]}
do
if systemctl is-active –quiet $service
then
echo « ✓ Le service $service est actif »
else
echo « ✗ Le service $service est inactif »
fi
done
Cette variante combine la boucle for avec une structure conditionnelle if/else. Pour chaque service, la commande systemctl is-active –quiet retourne un code de sortie zéro si le service fonctionne, ou un code non-zéro s’il est arrêté. La structure conditionnelle teste ce code et affiche le message approprié.
L’option –quiet supprime l’affichage textuel habituel de systemctl, permettant une utilisation purement conditionnelle du code de sortie. Cette technique de programmation shell offre une clarté remarquable et facilite l’intégration dans des pipelines de monitoring.
🚨 Construire un rapport de statut détaillé
Pour un monitoring avancé, combiner les vérifications de statut avec des métadonnées supplémentaires enrichit considérablement la valeur des rapports générés. Une boucle for peut extraire le PID du service, le propriétaire du processus, l’usage mémoire et d’autres indicateurs pertinents :
#!/bin/bash
echo « === Rapport de statut des services === »
services=(« ssh » « apache2 » « mysql »)
for service in ${services[@]}
do
echo « »
echo « Service : $service »
systemctl status –no-pager $service | grep « Active: »
systemctl show -p MainPID $service
done
Ce script génère un rapport structuré affichant l’état du service et son identificateur de processus (PID). Les administrateurs peuvent ainsi identifier rapidement quel service dysfonctionne et obtenir les informations nécessaires pour diagnostiquer les problèmes.
| 🔧 Tâche | 💻 Commande | 📊 Cas d’usage |
|---|---|---|
| Redémarrer un service | systemctl restart $service | Appliquer des modifications de configuration |
| Arrêter un service | systemctl stop $service | Libérer des ressources système |
| Démarrer un service | systemctl start $service | Relancer après maintenance |
| Vérifier l’état | systemctl is-active $service | Monitoring de disponibilité |
| Afficher le statut complet | systemctl status $service | Diagnostic détaillé |
| Activer au démarrage | systemctl enable $service | Persistance après redémarrage système |
Le guide sur la maîtrise des boucles for en Bash présente les deux syntaxes principales, leur utilisation pour traiter des listes, des plages numériques ou des fichiers, et fournit des astuces essentielles pour structurer des scripts puissants
🎓 Maîtriser les instructions de contrôle within et break continue
Les instructions break et continue modifient le déroulement d’une boucle for en Bash : break interrompt immédiatement la boucle, tandis que continue saute à l’itération suivante, permettant de contrôler finement le flux selon des conditions spécifiques.
Au-delà de la simple itération linéaire, les boucles for gagnent en puissance lorsqu’elles intègrent des instructions de contrôle de flux. Les commandes break et continue permettent de modifier le déroulement de la boucle selon les conditions rencontrées, offrant un contrôle fin sur l’exécution des itérations.
L’instruction break termine immédiatement la boucle, indépendamment du nombre d’itérations restantes. Celle-ci s’avère utile lorsqu’une condition critique est détectée et que poursuivre n’apporterait aucun bénéfice. L’instruction continue, en revanche, saute l’exécution du reste du corps de la boucle pour cette itération et passe directement à la suivante.
Considérez un script recherchant un utilisateur spécifique dans une liste. Une fois trouvé, la poursuite de la recherche devient superflue :
#!/bin/bash
utilisateurs=(« alice » « bob » « charlie » « diana »)
recherche= »charlie »
for utilisateur in ${utilisateurs[@]}
do
if [ « $utilisateur » == « $recherche » ]
then
echo « Utilisateur trouvé : $utilisateur »
break
fi
done
Dès que l’itération rencontre « charlie », la commande break termine la boucle immédiatement. Sans cette instruction, la boucle continuerait à itérer inutilement sur « diana ».
⏭️ Sauter les itérations indésirables avec continue
L’instruction continue s’avère particulièrement utile pour filtrer les éléments à traiter. Imaginons un script processant une liste de fichiers mais devant ignorer ceux disposant d’une extension particulière :
#!/bin/bash
for fichier in *
do
if [[ « $fichier » == *.tmp ]]; then
continue
fi
echo « Traitement : $fichier »
done
Ce script traverse tous les fichiers du répertoire courant, mais saute les fichiers .tmp. L’instruction continue maintient le contrôle de la boucle active tout en omettant le traitement pour cette itération particulière. Cette approche reste plus flexible que de préfiltrer la liste en amont, car elle permet des décisions dynamiques selon le contenu ou les attributs du fichier.
🔑 Combinaison avancée : break, continue et variables de contrôle
Pour des scénarios complexes, combiner break et continue avec des variables de contrôle offre une flexibilité remarquable. Supposons un script parcourant un journal système et devant arrêter au premier message critique détecté tout en ignorant les entrées sans rapport :
#!/bin/bash
for ligne in $(cat /var/log/syslog)
do
if [[ $ligne == * »CRITICAL »* ]]; then
echo « Alerte critique détectée : $ligne »
break
elif [[ $ligne == * »IGNORE »* ]]; then
continue
else
echo « Ligne standard : ${ligne:0:50}… »
fi
done
Cet exemple illustre la puissance de combiner les structures conditionnelles avec les instructions de contrôle de flux. Le script traite chaque ligne du journal, appliquant différentes logiques selon le contenu.
Pour documenter un script Bash, commencez toujours par une en-tête avec objectif, auteur, date et dépendances : cela facilitera la maintenance et le partage en équipe.
🚀 Techniques avancées et bonnes pratiques pour optimiser les boucles for
Au-delà des cas d’usage basiques, maîtriser les techniques avancées de boucles for en Bash permet de créer des scripts robustes, performants et maintenables. Plusieurs pratiques et motifs éprouvés ressortent de l’expérience collective des administrateurs et développeurs travaillant avec des scripts shell.
La première considération porte sur la gestion des erreurs. Une boucle traitant des fichiers ou exécutant des commandes système doit gérer les cas où une itération échoue. L’utilisation de sets -e ou la vérification individuelle des codes de sortie permet de détecter les problèmes et d’interrompir l’exécution avant d’aggraver les dégâts :
#!/bin/bash
set -e
for fichier in *.txt
do
if ! cp « $fichier » /backup/; then
echo « Erreur lors de la sauvegarde de $fichier » >&2
exit 1
fi
done
L’option set -e ordonne au script de s’arrêter dès qu’une commande retourne un code de sortie non-zéro. Les tests explicites offrent davantage de contrôle, permettant une gestion personnalisée des erreurs.
📈 Optimisation de performance et parallélisation
Lorsqu’une boucle for traite un grand nombre d’éléments, l’exécution séquentielle peut devenir chronophage. Dans certains contextes, paralléliser le traitement sur plusieurs processus accélère considérablement l’opération globale. Bash offre plusieurs mécanismes pour cela, y compris l’utilisation du ampersand (&) pour lancer les tâches en arrière-plan.
Voici un exemple où les fichiers sont copiés en parallèle plutôt que séquentiellement :
#!/bin/bash
for fichier in *.iso
do
cp « $fichier » /archive/ &
done
wait
Le caractère & lance chaque opération cp en arrière-plan. L’instruction wait en fin de boucle s’assure que tous les processus enfants se terminent avant que le script ne termine. Cette approche offre un parallélisme contrôlé idéal pour les tâches indépendantes.
🛡️ Gestion des caractères spéciaux et des noms de fichiers problématiques
L’un des défis majeurs dans la syntaxe bash consiste à gérer correctement les fichiers dont les noms contiennent des espaces, des guillemets ou d’autres caractères spéciaux. Ne pas encapsuler les variables entre guillemets constitue la source d’erreurs la plus fréquente en programmation shell.
Voici une approche sûre utilisant le -print0 de find combiné à while pour itérer sans risque :
#!/bin/bash
find . -name « *.txt » -print0 | while IFS= read -r -d » fichier
do
mv « $fichier » « ${fichier%.*}_archive.txt »
done
Cette construction utilise -print0 qui délimite les noms de fichiers avec des caractères nul plutôt que des retours à la ligne, et -d » indique à read de terminer au caractère nul. Cette technique, bien que plus complexe, gère correctement les fichiers aux noms exotiques.
📝 Documentation et maintenabilité des scripts
Pour les scripts destinés à l’utilisation professionnelle ou à la maintenance à long terme, la documentation intégrée revêt une importance capitale. Ajouter des commentaires clairs, utiliser des noms de variables explicites et structurer le code avec des sections facilitent la compréhension et la modification ultérieure.
- 🔹 Utiliser des noms de variables descriptifs (éviter i, j, f au profit de compteur, fichier, service)
- 🔹 Ajouter des commentaires expliquant les sections complexes ou les logiques subtiles
- 🔹 Mettre en place une en-tête de script documentant l’objectif, l’auteur et les dépendances
- 🔹 Employer une indentation cohérente pour améliorer la lisibilité structurelle
- 🔹 Utiliser set -x en cas de debugging pour afficher les commandes exécutées
- 🔹 Implémenter des messages d’erreur clairs utilisant >&2 pour la sortie d’erreur
Un exemple de script bien documenté ressemblerait à ceci :
#!/bin/bash
# Script : sauvegarde_automatique.sh
# Description : Archive les fichiers texte modifiés aujourd’hui
# Auteur : Équipe système
# Date création : 2026
#
# Dépendances : find, tar, gzip
set -e # S’arrêter en cas d’erreur
REPERTOIRE_SOURCE= »/home/utilisateur/documents »
REPERTOIRE_ARCHIVE= »/archive/backups »
DATE=$(date +%Y%m%d)
echo « Début de l’archivage : $DATE »
for fichier in $(find « $REPERTOIRE_SOURCE » -name « *.txt » -mtime 0)
do
nom_archive= »${REPERTOIRE_ARCHIVE}/${DATE}_$(basename « $fichier ») »
cp « $fichier » « $nom_archive »
echo « Archivé : $fichier »
done
echo « Archivage terminé »
Cette structure claire avec variables nommées, commentaires d’en-tête et messages informatifs rend le script accessible même à des développeurs n’ayant pas participé à sa création initiale. Les variables d’environnement facilitent l’adaptation à différents contextes d’exécution.
Les boucles for en Bash constituent un élément fondamental de l’automatisation système, permettant de transformer des processus manuels répétitifs en exécutions rapides et fiables. Que ce soit pour traiter des fichiers, gérer des services ou itérer sur des données numériques, maîtriser les deux syntaxes, les structures conditionnelles et les instructions de contrôle de flux ouvre des perspectives considérables pour les administrateurs et développeurs. En appliquant les bonnes pratiques de gestion d’erreurs, de documentation et d’optimisation, chacun peut construire des scripts robustes, maintenables et efficients qui se déploient en environnement professionnel avec assurance.








