Bash : conditions et boucles
Les conditions et les boucles contrôlent le déroulement d’un script. Les exemples utilisent des noms génériques.
if [[ -f "$fichier" ]]; then echo "Le fichier existe"elif [[ -d "$fichier" ]]; then echo "C'est un dossier"else echo "Introuvable"fiLes doubles crochets [[ ... ]] sont la forme recommandée dans un script Bash ; les crochets simples [ ... ] fonctionnent aussi dans sh, mais sont plus fragiles (guillemets obligatoires).
if teste le code de sortie d’une commande : toute commande peut servir de condition.
if grep -q "erreur" journal.log; then # -q : n'affiche rien, ne sert qu'au code de sortie echo "Des erreurs ont été trouvées"fi
if ! systemctl is-active --quiet ssh; then echo "SSH est arrêté"fiTests sur les fichiers
Section intitulée « Tests sur les fichiers »| Test | Vrai si |
|---|---|
-e f |
f existe |
-f f |
f est un fichier ordinaire |
-d f |
f est un dossier |
-r f / -w f / -x f |
f est lisible / modifiable / exécutable |
-s f |
f existe et n’est pas vide |
-L f |
f est un lien symbolique |
f1 -nt f2 |
f1 est plus récent que f2 |
Tests sur les chaînes
Section intitulée « Tests sur les chaînes »| Test | Vrai si |
|---|---|
-z "$s" |
la chaîne est vide |
-n "$s" |
la chaîne n’est pas vide |
"$a" == "$b" |
les chaînes sont égales |
"$a" != "$b" |
les chaînes sont différentes |
"$s" == motif* |
la chaîne correspond au motif (sans guillemets sur le motif) |
"$s" =~ ^[0-9]+$ |
la chaîne correspond à l’expression régulière |
if [[ "$reponse" == [oO]* ]]; then echo "Oui"; fiif [[ "$age" =~ ^[0-9]+$ ]]; then echo "Nombre entier"; fiTests sur les nombres
Section intitulée « Tests sur les nombres »| Test | Signification |
|---|---|
-eq / -ne |
égal / différent |
-lt / -le |
inférieur / inférieur ou égal |
-gt / -ge |
supérieur / supérieur ou égal |
if [[ "$nb" -gt 10 ]]; then echo "Plus de 10"; fiif (( nb > 10 )); then echo "Plus de 10"; fi # forme arithmétique, plus lisibleCombiner des conditions
Section intitulée « Combiner des conditions »if [[ -f "$f" && -r "$f" ]]; then echo "Fichier lisible"; fiif [[ "$a" == "x" || "$b" == "y" ]]; then echo "Au moins une vraie"; fi
[[ -d "$dossier" ]] || mkdir -p "$dossier" # crée le dossier s'il manquecommand -v rsync >/dev/null && echo "rsync est installé"Alternative lisible à plusieurs if successifs :
case "$1" in start) echo "Démarrage" ;; stop|arret) echo "Arrêt" ;; *.txt) echo "Fichier texte" ;; *) echo "Usage : $0 {start|stop}" >&2 exit 1 ;;esacBoucle for
Section intitulée « Boucle for »for fruit in pomme poire cerise; do echo "$fruit"done
for fichier in *.log; do # fichiers du dossier courant echo "Traitement de $fichier"done
for i in {1..5}; do echo "$i"; done # de 1 à 5
for ((i = 0; i < 5; i++)); do # boucle « à la C » echo "$i"doneBoucles while et until
Section intitulée « Boucles while et until »compteur=1while (( compteur <= 3 )); do echo "Tour $compteur" (( compteur++ ))done
until ping -c 1 -W 2 exemple.com >/dev/null 2>&1; do # jusqu'à ce que la commande réussisse echo "En attente du réseau..." sleep 5doneLire un fichier ligne par ligne
Section intitulée « Lire un fichier ligne par ligne »while IFS= read -r ligne; do echo "Ligne : $ligne"done < fichier.txtIFS= et -r conservent les espaces et les antislashs tels quels. Pour traiter la sortie d’une commande :
while IFS= read -r utilisateur; do echo "Utilisateur : $utilisateur"done < <(cut -d: -f1 /etc/passwd)Interrompre une boucle
Section intitulée « Interrompre une boucle »for n in {1..10}; do (( n % 2 == 0 )) && continue # passe au tour suivant (( n > 7 )) && break # sort de la boucle echo "$n"donePoser une question à l’utilisateur
Section intitulée « Poser une question à l’utilisateur »read -r -p "Continuer ? [o/N] " reponseif [[ "$reponse" =~ ^[oO]$ ]]; then echo "On continue"else echo "Annulé" exit 0fiPour aller plus loin
Section intitulée « Pour aller plus loin »- Manuel : Conditional Constructs