Les instructions en boucle sont utilisées pour forcer un programme à exécuter une instruction de manière répétée. L'instruction exécutée est appelée le corps de la boucle.
Les boucles s'exécutent jusqu'à ce que la valeur d'une expression de contrôle soit 0. L'expression de contrôle peut être n'importe quel type de données scalaire.
Le langage shell fournit également plusieurs instructions d'itération ou de boucle. Dans cet article, passons en revue les instructions en boucle fournies par bash à l'aide de quelques exemples.
Bash prend en charge les trois types d'instructions en boucle suivants
- Boucle For
- Boucle While
- Jusqu'à la boucle
Cet article fait partie de la série de tutoriels Bash en cours.
Les boucles peuvent être imbriquées. Comme tout autre langage de programmation, bash prend également en charge l'instruction break pour quitter la boucle en cours et l'instruction continue pour reprendre la prochaine itération de l'instruction de boucle.
Bash For Loop – Première méthode
Les boucles for sont généralement utilisées lorsque le nombre d'itérations est connu avant d'entrer dans la boucle bash. Bash prend en charge deux types de boucle for. La première forme de bash for loop est :
for varname in list do commands ##Body of the loop done
Dans la syntaxe ci-dessus :
- for, in, do et done sont des mots clés
- La liste est une liste contenant une liste d'éléments
- varname est n'importe quel nom de variable Bash.
Sous cette forme, l'instruction for exécute la commande contenue dans un corps, une fois pour chaque élément de la liste. L'élément actuel de la liste sera stocké dans une variable "varname" à chaque fois dans la boucle. Ce varname peut être traité dans le corps de la boucle. Cette liste peut être une variable contenant plusieurs mots séparés par des espaces. Si la liste est manquante dans l'instruction for, elle prend le paramètre de position qui a été transmis au shell.
Bash For Loop Example 1. Décompressez tout le fichier Zip
L'exemple suivant trouve la liste des fichiers qui correspondent à "*.zip*" dans le répertoire racine, et crée un nouveau répertoire au même emplacement où le fichier zip existe, et décompresse le contenu du fichier zip.
# cat zip_unzip.sh #! /bin/bash # Find files which has .zip for file in `find /root -name "*.zip*" -type f` do # Skip the extension .zip dirname=`echo ${file} | awk -F'.' '{print $1}'` # Create the directory mkdir $dirname # Copy the zip file cp ${file} ${dirname} cd $dirname # Unzip the zip file from newly created directory unzip ${dirname}/$(echo ${file##/*/}) done
- Dans cet exemple, la commande find renvoie la liste des fichiers, à partir de laquelle chaque fichier sera traité via une boucle.
- Pour chaque élément, il crée le répertoire avec le nom du fichier zip, copie le fichier zip dans le répertoire nouvellement créé et décompresse le fichier zip à partir de là.
- L'instruction echo, echo ${file##/*/} vous donne uniquement le nom du fichier et non le chemin.
# ./zip_unzip.sh Archive: /root/test2/test2.zip extracting: t1/p extracting: t1/q extracting: t1/r extracting: t1/s extracting: t1/t extracting: t1/u extracting: t1/v Archive: /root/test1/test1.zip extracting: t/a extracting: t/b extracting: t/c extracting: t/d extracting: t/e
Semblable à la boucle Bash, Awk fournit également une boucle for et une boucle while comme nous en avons discuté dans notre article Awk While et For Loop.
Bash For Loop - Deuxième méthode
La deuxième forme de boucle for est similaire à la boucle for du langage de programmation "C", qui comporte trois expressions (initialisation, condition et mise à jour).
for (( expr1; expr2; expr3 )) do commands done
- Dans le bash ci-dessus pour la syntaxe de commande, avant la première itération, expr1 est évalué. Ceci est généralement utilisé pour initialiser les variables de la boucle.
- Toutes les instructions entre do et done sont exécutées de manière répétée jusqu'à ce que la valeur de expr2 soit TRUE.
- Après chaque itération de la boucle, expr3 est évalué. Ceci est généralement utilisé pour incrémenter un compteur de boucle.
L'exemple suivant génère le nombre n de nombres aléatoires.
Bash pour l'exemple 2. Générer n nombres aléatoires
$ cat random.sh #! /bin/bash echo -e "How many random numbers you want to generate" read max for (( start = 1; start <= $max; start++ )) do echo -e $RANDOM done $ ./random.sh How many random numbers you want to generate 5 6119 27200 1998 12097 9181
Dans l'extrait de code ci-dessus, la boucle for génère le nombre aléatoire au nombre maximum de fois. RANDOM est une fonction bash interne qui renvoie un entier aléatoire à chaque invocation.
Bash While Boucle
Une autre instruction d'itération offerte par le langage de programmation shell est l'instruction while.
Syntax: while expression do commands done
Dans la syntaxe de la boucle while ci-dessus :
- while, do, done sont des mots clés
- Expression est toute expression qui renvoie une valeur scalaire
- L'instruction While entraîne l'exécution d'un bloc de code alors qu'une expression conditionnelle fournie est vraie.
Bash While Exemple 3. Écrire le contenu dans un fichier
L'exemple suivant lit les données de la sortie standard et les écrit dans un fichier.
$ cat writefile.sh #! /bin/bash echo -e "Enter absolute path of the file name you want to create" read file while read line do echo $line >> $file done $ sh writefile.sh Enter absolute path of the file name you want to create /tmp/a while for until $ cat /tmp/a while for until
L'exemple ci-dessus lit le nom de fichier de l'utilisateur, lit les lignes de données de stdin et ajoute chaque ligne à un nom de fichier donné. Lorsque EOF entre, la lecture échoue, donc la boucle s'arrête là.
Si vous écrivez beaucoup de scripts bash, vous pouvez utiliser l'éditeur Vim comme IDE Bash en utilisant le plugin Vim bash-support comme nous l'avons vu précédemment.
Bash While Exemple 4. Lire le contenu d'un fichier
Dans l'exemple précédent, il lit les données de stdout et les écrit dans un fichier. Dans cet exemple, il lit le contenu du fichier
et l'écrit dans une sortie standard.
$ cat read.sh #! /bin/bash echo -e "Enter absolute path of the file name you want to read" read file exec <$file # redirects stdin to a file while read line do echo $line done $ ./read.sh Enter absolute path of the file name you want to read /tmp/a while for until
Dans cet exemple, il obtient le nom de fichier à lire et, à l'aide de exec, il redirige stdin vers un fichier. À partir de ce moment, tout stdin provient de ce fichier, plutôt que du clavier. La commande read lit la ligne à partir de stdin, donc pendant que la boucle lit le stdin, jusqu'à ce que EOF se produise.
Bash jusqu'à la boucle
L'instruction until est très similaire en syntaxe et en fonction à l'instruction while. La seule vraie différence entre les deux est que l'instruction until exécute son bloc de code alors que son expression conditionnelle est fausse, et l'instruction while exécute son bloc de code alors que son expression conditionnelle est vraie.
syntax: until expression do commands #body of the loop done
Dans la syntaxe bash until ci-dessus :
où until, do, done sont des mots clés
expression toute expression conditionnelle
Bash jusqu'à l'exemple 5. Surveiller le fichier journal
Cet exemple surveille la taille du fichier journal, une fois que la taille du fichier journal atteint 2000 octets, il prend la copie de ce fichier journal.
$ cat monitor.sh file=/tmp/logfile until [ $(ls -l $file | awk '{print $5}') -gt 2000 ] do echo "Sleeping for next 5 seconds" sleep 5 done date=`date +%s` cp $file "$file-"$date.bak $ ./monitor.sh Sleeping for next 5 seconds Sleeping for next 5 seconds $ ls -l /tmp/logfile* -rw-r--r-- 1 sss sss 2010 Jun 24 12:29 logfile -rw-r--r-- 1 sss sss 2005 Jun 24 16:09 logfile-1277474574.bak
L'instruction until continue d'exécuter le corps de la boucle jusqu'à ce que la condition devienne vraie. Dans cet exemple, la condition est la taille du fichier supérieure à 2000 octets, donc il copie le fichier une fois qu'il atteint les 2000 octets.
Assurez-vous également de vous référer à nos exemples précédents de Bash Array.
Bash jusqu'à l'exemple 6. Attendre que la machine se lance
Cet exemple est utilisé pour attendre que la machine démarre avant de faire un ssh à cette machine. L'instruction de boucle until ne se termine que lorsque le ping donne les réponses.
$ cat mac_wait.sh #! /bin/bash read -p "Enter IP Address:" ipadd echo $ipadd until ping -c 1 $ipadd do sleep 60; done ssh $ipadd $./mac_wait.sh Enter IP Address:192.143.2.10 PING 192.143.2.10 (192.143.2.10) 56(84) bytes of data. --- 192.143.2.10 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms PING 192.143.2.10 (192.143.2.10) 56(84) bytes of data. 64 bytes from 192.143.2.10: icmp_seq=1 ttl=64 time=0.059 ms --- 192.143.2.10 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.059/0.059/0.059/0.000 ms The authenticity of host '192.143.2.10 (192.143.2.10)' can't be established. Are you sure you want to continue connecting (yes/no)? yes
La boucle Until est très utile en ligne de commande, comme moyen d'attendre que certains événements se produisent.