Aujourd'hui je reviens avec un petit baratin sur les boucles dans les scripts bash. C'est très superficiel, mais ça peut servir de point de départ aux débutants qui nous lisent.
Bash permet de gérer les types classiques de boucles : for, while, et until. Et cela n'a rien de bien excitant, je vous l'accorde. Ce qui est plus intéressant ce sont les multiples moyens que l'on a de "nourrir" ces boucles.
Passons tout d'abord sur les généralités.
La boucle for.
Elle s'articule autour de ce schéma :
for VAR in LISTE do # actions done
VAR est ma variable, LISTE est une liste d'éléments. Cela donne par exemple :
for i in 1 2 3 do echo "i =" $i done
résultat :
i = 1 i = 2 i = 3
Il existe néanmoins un schéma alternatif à cette syntaxe. Il est possible de définir une boucle for selon le modèle suivant :
for ((initialisation de VAR; contrôle de VAR; modification de VAR)) do # actions done
Ce qui permet par exemple de coder un compte à rebours de 10 à 0:
for ((i = 10; i >= 0; i -= 1)) do echo $i done
La boucle while.
La boucle while s'écrit sous cette forme générale :
while CONDITION do # actions done
CONDITION est une condition de continuation de la boucle. Tant que cette condition est vraie, la boucle continue. Il faut presque toujours définir les variables de CONDITION avant le while, sinon la condition n'est pas vérifiable. Mais nous verrons qu'il y a une exception.
Un exemple pour la route :
i=0 while [ $i -le 10 ] do echo $i let i=1+$i done
Je pose que i vaut 0, et je dis que ma boucle doit s'exécuter tant que i est inférieur ou égal à 10 (man test pour la syntaxe dans les crochets). Remarquez que je suis obligé d'incrémenter manuellement le compteur i.
Comme pour for, on peut recourir à cette syntaxe :
i=0 while ((i <= 10)) do echo $i ((i += 1)) done
Cependant, l'utilisation des crochets offre une plus grande richesse.
La boucle until.
Elle est tout à fait comparable à la boucle while, donc je ne rentre pas dans les détails. Par contre, elle se différencie de cette dernière par le fait que la condition est une condition d'arrêt, et non de continuation, de la boucle.
Donc la boucle until s'arrête quand CONDITION est vraie, alors que la boucle while continue tant que CONDITION est vraie.
Nourrir le monstre.
Maintenant que l'on a de quoi faire des boucles, intéressons-nous aux moyens de les alimenter.
La boucle for est la plus simple à faire fonctionner pour le novice car elle parcoure une liste définie d'éléments.
Cette liste peut être totalement statique, elle peut être une variable définie précédemment dans le script, ou elle peut être obtenue à partir d'une commande. Par ex :
for i in `jot -r 5` do echo $((i-100)) done
jot est une commande de Mac OS X (et FreeBSD entre autre) qui permet de générer toutes sortes de séries de chiffres ou de lettres. Ici la commande `jot -r 5
` génère 5 nombres aléatoires. On peut remplacer le `echo $((i-100))
` par quelque chose de plus intéressant ;).
Il y a bien d'autres moyens d'écrire cette même boucle. Deux exemples au hasard :
for i in `jot -r 5`; do echo $((i-100)); done
et
for i in $(jot -r 5); do echo $((i-100)) done
Si vous souhaitez aller plus loin et découvrir le potentiel de jot, seq et bash dans la génération de séquences de chiffres ou de lettres, n'hésitez pas à lire cet article : jot et seq, créer des séquences en ligne de commande.
Pour les boucles while et until, la contrainte est différente. Peu importe ce qu'on donne à l'opérateur, ce qui est pris en compte c'est le status (vrai ou faux, succès ou échec, ...). En général, ce status est obtenu à partir d'un test :
while [ "$var" = "toto" ]; do # actions done
Mais on peut aussi nourrir une boucle while (plus rarement until) avec d'autres choses, comme un fichier texte :
num=0 while read ligne; do num=$((num+1)) echo "$num $ligne" done < /etc/passwd
Dans ce cas, la boucle s'arrête quand il n'y a plus de ligne à lire dans le fichier. La syntaxe "read VARIABLE" est utilisable aussi dans le cas d'un résultat de commande, mais il faut alors utiliser un pipe pour nourrir le "read" :
num=0 ls | while read ligne; do num=$((num+1)) echo "$num $ligne" done
Voilà un tour sommaire sur les boucles en bash.
La discussion a lieu par ici.
Pour aller un peu plus loin, n'hésitez pas à consulter les autres articles qui parlent de bash !
je ve faire un programme en bache qui génére un nombre aleatoire et qui demande a l"utilisateur de entrer un nombre j'usqu'as qu'il trouve le nombre mystere et en m^m temp reduire la plage du RANDOM du 32767 a 100 autrement dit le bombre mystere doit pas deppaser 100 voila merci bq
C'est gentil de passer nous voir, mais en général je me fais payer pour faire le boulot des autres.
Rapidement, sans trop tester, voici un début de piste :
Un grand merci pour ces pages d'une grande qualité sur bash.
J'ai eu besoin d'info pour automatiser un traitement ocr avec tesseract de plusieurs pages et vos pages ont été très utiles.
Un travail propre et pro, trop rare sur le web.
Bonne continuation ;)