======C18 : Bash : Structures conditionnelles, boucles et calculs====== =====Objectifs :===== * Savoir réaliser des opérations simples en bash * Être capable d’utiliser dans vos scripts les instructions IF, WHILE et FOR =====Cours===== ==== 1 - Arithmétique en bash ==== ===Introduction=== Soyons clairs tout de suite : __**Bash n'est PAS un langage pensé pour manipuler des nombres !**__ (vous vous rappellerez peut-être que je vous avais indiqué que, pour Bash, **toute variable est une chaine de caractères** ?) Ceci étant dit, vouloir coder n’importe quoi d’un peu évolué sans jamais utiliser de nombres est une illusion, aussi va-t-il falloir apprendre comment ça marche. Si vous tapez : echo 1+2 Vous obtiendrez 1+2 Eh oui, par défaut, **tout est une chaine de caractère en bas**h, et donc ma belle opération ne s’exécute pas. Il s'agit pour le langage d'une suite de caractères comme n'importe laquelle. ===Syntaxe pour effectuer des calculs=== Si vous voulez que bash fasse un calcul, il faut l’entourer de **doubles parenthèses**. Par exemple, si je tape : ((3+4)) Il ne s’affiche rien. Rien, mais **pas non plus d’erreur**, ce qui serait arrivé si vous aviez tapé : 3+4 Et en effet, quand vous avez tapé %%((3+4))%%, tout s’est bien passé. Votre **commande** a été bien comprise par l'interpréteur. C’est juste que par défaut, **l’opérateur %%((%%** n’affiche rien sur la sortie standard. Si vous voulez récupérer la valeur de votre opération, ce qui sera souvent le cas, alors il faut mettre un **$ devant les doubles parenthèses**, ce qui vous donne par exemple : $ echo $((1+2)) 3 Et là c’est merveilleux, vous avez réussi votre première opération en bash. Ça fonctionne de la même façon pour vos **quatre opérations de base** : + ; - ; * ; / Toutefois, j’attire votre attention sur le fait que, si bash n’est guère fait pour manipuler des nombres, il n’est définitivement **pas pensé pour gérer les nombres réels** (vous savez, ces choses avec des virgules). Donc si vous vous lancez dans des divisions, **soyez certains de l’intérêt**, et il vaudrait mieux que ça tombe sur des nombres entiers sinon vous allez au-devant de surprises (essayez, vous verrez !). ===Syntaxe avancée=== En plus des opérations classiques, vous avez accès à tout un tas d’opérateurs, et ne vous servirez sans doute jamais ou presque d’une majorité d’entre eux. Mais bon, si vous cherchez quelque chose de précis un jour : * [[promo_2026:bloc1_sys_reseau:bash_operateurs | Bash : opérateurs de calcul]] Pour vous, dans la pratique, ça devrait se limiter à ceci (exemples ci-dessous, avec deux variables a et b) : * Addition : %%((a+b))%% * Soustraction : %%((a-b))%% * Multiplication : %%((a*b))%% * Division entière : %%((a/b))%% * Reste de la division : %%((a%b))%% * Mise en exposant (de la 2e variable) : %%((a**b))%% * Incrémentation : %%((a++))%% (ajoute 1 à la valeur de a) # Affectation des valeurs 4 et 5 aux variables a et b sio@demo:~$ a=4 sio@demo:~$ b=5 # Exemple d'affiche du résultat d'opérations sio@demo:~$ echo $((a+b)) 9 sio@demo:~$ echo $((a-b)) -1 sio@demo:~$ echo $((a*b)) 20 sio@demo:~$ echo $((a/b)) 0 sio@demo:~$ echo $((a%b)) 4 sio@demo:~$ echo $((a**b)) 1024 sio@demo:~$ echo $((b++)) 6 # Comme l'on vient d'augmenter la valeur de b : sio@demo:~$ echo $b 6 # Calcul avec un opérateur d'affectation (affecte le résultat à la première variable du calcul) : sio@demo:~$ ((a*=b)) sio@demo:~$ echo $a 24 ==== 2 - Structures conditionnelles ==== Comme tout langage de programmation, Bash dispose de structures de contrôle. La première que nous allons voire est la commande if. Au premier abord, la syntaxe est simple : if condition ; then instructions else instructions fi Vous pouvez également utiliser elif pour else if (si condition de if non validée, deuxième condition) : if condition ;then instructions elif condition ; then instructions else instructions fi On peut enchainer plusieurs elif si besoin, mais ayez bien conscience que **si une condition est validée, les suivantes ne seront pas vérifiées**. Il faut donc bien réfléchir à l’ordre dans le cas des conditions multiples. Il doit y avoir **exactement un fi par if**, pas besoin de mettre de fi pour un elif. **Après chaque condition**, il doit y avoir un **then**. Il n’est absolument pas obligatoire d’inclure de clauses else ou elif. :!:Il faut bien écrire if, then, else, elif, et fi en minuscules.:!: C’est pour les conditions que les choses se compliquent un peu. Il faut séparer deux cas : ===A – Conditions sur les entiers=== Si vos conditions portent sur des **nombres entiers**, elles doivent être e**ntourées de double parenthèses** comme pour tout calcul, comme on a vu précédemment. Cela donne par exemple ceci : read number if (( $number >= 50 )) ; then echo "nombre saisi supérieur ou égal à 50" fi Les opérateurs utilisables sur les nombres sont les suivants : |Egal |==| |Différent |!=| |Strictement supérieur |>| |Strictement inférieur|<| |Supérieur ou égal|>=| |Inférieur ou égal|<=| Attention, **pas de $ devant ces doubles parenthèses-ci**, ce qui vous intéresse n’est pas la valeur de votre calcul mais le code de retour de l’expression, qui déclenchera la validation ou non du test IF. ===B – Autres conditions=== Si ce que vous voulez tester n’est pas à proprement parler un calcul sur des nombres entiers (comme tout ce qu’on a fait jusque-là), alors il faudra utiliser les **doubles crochets**. :!:Des doubles crochets doivent être **séparés de la condition à évaluer par un espace**, sans quoi rien ne marche.:!: Ca donne par exemple des choses comme ça : Script : #!/bin/bash read text if [[ $text < "o" ]] ;then echo "ce texte commence par une des 13 premières lettres de l'alphabet else echo "ce texte commence par une des 13 dernières lettres de l'alphabet fi Les opérateurs utilisables sur les nombres sont les suivants : |Egal |==| |Différent |!=| |Postérieur dans l’ordre alphabétique |>| |Antérieur dans l’ordre alphabétique |<| :!:Les opérateurs de comparaison de chaines doivent être encadrés par des espaces, sans quoi des choses étonnantes se produisent.:!: ==== 3 - Les boucles ==== En programmation, une boucle est une structure logique définissant la **répétition d’instructions** jusqu’à **validation d’une condition.** ===A – Boucle WHILE=== La boucle **while** (« tant que ») permet de répéter une série d’instructions tant qu’une **condition** vérifiée entre chaque exécution n’est **pas validée**. Sa structure est la suivante : while condition do instructions done Les conditions marchent **exactement pareil que pour if**. Par exemple : Script : #!/bin/bash i=0 while (( $i < 4 )) do ((i++)) echo "Et de $i !" done Exécution : Et de 1 ! Et de 2 ! Et de 3 ! Et de 4 ! Au passage, notez **l’instruction %%((i++))%%**. C’est ce que l’on appelle une **incrémentation** : on augmente la valeur de la variable i de +1 à chaque fois que cette instruction est répétée (cela aurait pu s’écrire %%((i=$i+1))%% mais c’est plus long). Les incrémentations sont à la base de la logique qui régit la majorité des boucles : on fait évoluer une variable / un compteur jusqu’à ce que la condition posée soit validée. ===B – Boucle FOR=== La boucle for (« jusqu’à ce que ») permet de répéter une série un **nombre défini de foi**s, la plupart du temps **via un compteur**. En bash, toutefois, elle est un peu spéciale. Contrairement à la plupart des autres langages, une boucle for va donner à son compteur les valeurs contenues dans une **liste de mots successifs**. Sa structure est la suivante : for i in listedemots do instructions done Par exemple, ce script : for i in "a" "b" "c" "d" "e" do echo $i done Donnera ceci : a b c d e (Au passage, il n’est pas impératif de mettre vos mots entre guillemets) Il est bien entendu possible de faire des boucles for davantage similaires aux autres langages, en proposant à la place de la liste de mots un **intervalle d’entiers** dont la syntaxe sera **{a..b} SANS ESPACES**. Ainsi, on aura pour ce script : for i in {1..4} do echo $i done Cette exécution : 1 2 3 4 Vous pouvez bien sûr utiliser des substitutions de commandes là-dedans : for i in $(ls) do echo $i done Ainsi, ce script va lister le contenu du dossier courant. Pratique ! file1 dir1 dir2 ===C - Pour aller plus loin=== A noter que les **boucles** peuvent être utilisées pour **parcourir des fichiers** et effectuer ainsi des opérations plus complexes, ou en tout cas plus lisibles, qu'avec des suites de pipe. Pour plus d'infos : * [[promo_2026:bloc1_sys_reseau:shell_scripting | Shell : Scripts]] =====Diaporama===== ==== 1 - Arithmétique en bash ==== ===Introduction=== __**Bash n'est PAS un langage pensé pour manipuler des nombres !**__ . ===== ===== ===Syntaxe pour effectuer des calculs=== Si vous voulez que bash fasse un calcul, il faut l’entourer de **doubles parenthèses**. ===== ===== ===Syntaxe avancée=== Multitude d’opérateurs : * [[promo_2026:bloc1_sys_reseau:bash_operateurs | Bash : opérateurs de calcul]] Pour vous, dans la pratique, ça devrait se limiter à ceci : * Addition : %%((a+b))%% * Soustraction : %%((a-b))%% * Multiplication : %%((a*b))%% * Division entière : %%((a/b))%% * Reste de la division : %%((a%b))%% * Mise en exposant (de la 2e variable) : %%((a**b))%% * Incrémentation : %%((a++))%% (ajoute 1 à la valeur de a) ===== ===== ==== 2 - Structures conditionnelles ==== if condition ; then instructions else instructions fi ===== ===== Vous pouvez également utiliser elif pour else if : if condition ;then instructions elif condition ; then instructions else instructions fi ===== ===== ===A – Conditions sur les entiers=== **Nombres entiers** = conditions **entourées de double parenthèses** ===== ===== Les opérateurs utilisables sur les nombres sont les suivants : |Egal |==| |Différent |!=| |Strictement supérieur |>| |Strictement inférieur|<| |Supérieur ou égal|>=| |Inférieur ou égal|<=| ===== ===== ===B – Autres conditions=== **doubles crochets** pour tout ce qui n'est pas nombres entiers ===== ===== Les opérateurs utilisables sur les nombres sont les suivants : |Egal |==| |Différent |!=| |Postérieur dans l’ordre alphabétique |>| |Antérieur dans l’ordre alphabétique |<| ===== ===== ==== 3 - Les boucles ==== ===A – Boucle WHILE=== while condition do instructions done ===== ===== ===B – Boucle FOR=== Un peu spéciale : liste de **"mots" successifs** plutôt qu'un compteur : for i in listedemots do instructions done ===== ===== ===C - Pour aller plus loin=== A noter que les **boucles** peuvent être utilisées pour **parcourir des fichiers** et effectuer ainsi des opérations plus complexes, ou en tout cas plus lisibles, qu'avec des suites de pipe. Pour plus d'infos : * [[promo_2026:bloc1_sys_reseau:shell_scripting | Shell : Scripts]]