Vous n'êtes pas identifié(e).
L'icône rouge permet de télécharger chaque page du wiki visitée au format
PDF et la grise au format ODT →
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente Prochaine révision Les deux révisions suivantes | ||
doc:programmation:shells:page-man-bash-iv-symboles-dans-les-calculs-mathematiques [10/04/2014 10:16] Hypathie [Page man bash V, Symboles dans les calculs mathématiques] |
doc:programmation:shells:page-man-bash-iv-symboles-dans-les-calculs-mathematiques [26/02/2023 21:09] agp91 [Opérateurs, priorités] |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ======Page man bash V, Symboles dans les calculs mathématiques====== | + | ======Bash : les symboles dans les calculs====== |
- | * Objet : Ne plus confondre les différents caractères de BASH | + | * Objet : suite de la série de wiki visant à maîtriser bash via les différents caractère spéciaux. |
- | * Niveau requis : {{tag>débutant}} | + | * Niveau requis : {{tag>débutant avisé}} |
* Commentaires : scripts | * Commentaires : scripts | ||
* Débutant, à savoir : [[:doc:systeme:commandes:le_debianiste_qui_papillonne|Utiliser GNU/Linux en ligne de commande, tout commence là !.]] :-) | * Débutant, à savoir : [[:doc:systeme:commandes:le_debianiste_qui_papillonne|Utiliser GNU/Linux en ligne de commande, tout commence là !.]] :-) | ||
- | * Suivi : {{tag>en-chantier à-tester à-placer}} | + | * Suivi : {{tag>en-chantier}} |
- | * Création par **Hypathie** 08/04/2014 | + | * Création par [[user>Hypathie]] le 08/04/2014 |
- | * Testé par <Hypathie> le <Avril 2014> | + | * Testé par [[user>Hypathie]] Avril 2014 |
- | * Commentaires sur le forum : [[debian-facile.org/viewtopic.php?pid=87499#p87499 | Lien vers le forum concernant ce tuto]] ((N'hésitez pas à y faire part de vos remarques, succès, améliorations ou échecs !)) FIXME | + | * Commentaires sur le forum : [[https://debian-facile.org/viewtopic.php?pid=140882#p140882 | ici]] ((N'hésitez pas à y faire part de vos remarques, succès, améliorations ou échecs !)) |
- | **Nota : suite du petit commentaire sur les caractères de la page man bash** | ||
- | 1) Intro I : [[atelier:chantier:bash-les-differents-caracteres-speciaux#meta-caracteres-et-meta-caracteres]]\\ | + | * [[doc:programmation:shells:bash-les-differents-caracteres-speciaux|Vision d'ensemble]] |
+ | * [[doc:programmation:shells:la-page-man-bash-les-caracteres-speciaux|Détail et caractères]] | ||
+ | * [[doc:programmation:shells:la-page-man-bash-ii-les-operateurs-lexicographiques|Les opérateurs lexicographiques]] | ||
+ | * [[doc:programmation:shells:page-man-bash-iii-les-operateurs-de-comparaison-numerique|Les opérateurs de comparaison numérique]] | ||
+ | * ;-) | ||
+ | * [[doc:programmation:shells:page-man-bash-v-les-tableaux|Les tableaux]] | ||
+ | * [[doc:programmation:shells:man-bash-vi-les-caracteres-de-transformation-de-parametres|Les caractères de transformation de paramètres]] | ||
+ | * [[doc:programmation:shells:bash-vii-globs-etendus-regex| Bash : Variables, globs étendus, ERb, ERe]] | ||
- | 2) chap II : [[atelier:chantier:la-page-man-bash-les-caracteres-speciaux]]\\ | + | <note important> |
+ | Page en court de réécriture | ||
+ | </note> | ||
+ | ===== Introduction ===== | ||
- | 3) chap III : [[atelier:chantier:la-page-man-bash-ii-les-operateurs-lexicographiques|opérateurs lexicographiques]]\\ | + | Dans la page précédente ([[doc:programmation:shells:page-man-bash-iii-les-operateurs-de-comparaison-numerique|Les opérateurs de comparaison numérique]]), nous avons abordé la commande interne **let** et la commande composée **<nowiki>((...))</nowiki>**.\\ |
+ | Nous complémentons ici leurs usages, pour réaliser des opérations mathématiques. | ||
- | 4) chap IV : [[atelier:chantier:page-man-bash-iii-les-operateurs-de-comparaison-numerique|opérateurs de comparaison numérique]]\\ | + | Les commandes **let** et **<nowiki>((...))</nowiki>** sont les seules commandes internes que bash dispose pour réaliser des opérations mathématiques.\\ |
+ | A travers elles, bash est limité à n'opérer que sur des entiers signés (positifs ou négatifs).\\ | ||
+ | Le résultat de l'évaluation d'une expression sera toujours un entier décimal signé. | ||
- | 5) chap V : C'est ici !\\ | + | Pour réaliser des opérations avec des nombres à virgule ou plus complexes, nous devons nous tourner vers des commandes externes tel que **bc** (non installé par défaut) ou **awk**. Ou alors utiliser d'autres langages interprétés tel que **perl**, **python**, etc (**awk**, **perl** et **python** sont disponibles par défaut sur les systèmes Debian). |
- | 6) chap VI : [[atelier:chantier:page-man-bash-v-les-tableaux|les tableaux]]\\ | + | Avec **let** et **<nowiki>((...))</nowiki>**, la plage numérique autorisée est : **-9223372036854775808 < 0 > 9223372036854775807** |
- | 7) chap VII : [[atelier:chantier:man-bash-vi-les-caracteres-de-transformation-de-parametres]]\\ | + | Après l'évaluation des expressions qu'elles contiennent, **let** et **<nowiki>((...))</nowiki>** renvoient le code de retour : |
- | 8) chap VIII : [[atelier:chantier:bash-vii-globs-etendus-regex]] | + | * **0**, si le résultat est inférieur ou supérieur à 0. |
+ | * **1**, si le résultat est égal à 0. | ||
- | Contributeurs, les FIXME sont là pour vous aider, supprimez-les une fois le problème corrigé ou le champ rempli ! | + | La commande **<nowiki>((...))</nowiki>** peut-être préfixée du caractère de remplacement **$** pour former la commande **<nowiki>$((...))</nowiki>**, afin d’être remplacée par l'évaluation de l’expression qu'elle contient. |
- | =====Symboles dans les calculs mathématiques ===== | + | <note warning> |
- | ====1) La construction :==== | + | La commande **$[...]** équivalente à la commande **<nowiki>$((..))</nowiki>** __**ne doit plus être utilisée**__.\\ |
- | <code> | + | \\ |
- | ((...)) | + | Elle est délaissée depuis la version 2.0 de bash au profit de **<nowiki>((...))</nowiki>**.\\ |
- | </code> permet une évaluation arithmétique. | + | \\ |
- | <code> | + | \\ |
- | #!/bin/bash | + | <file config Extrait de la page du manuel de bash> |
- | a=$(( 5 + 3 )) | + | L'ancien format $[expression] est obsolète et sera supprimé dans les prochaines versions de bash. |
- | echo $a # réponse 8 | + | </file> |
- | b=$(( 5 - 2 )) | + | \\ |
- | echo $b # réponse 3 | + | Pour des raisons de rétrocompatibilité, elle est toujours active dans nos bash modernes.\\ |
- | c=$(( 6 * 2 )) | + | Mais viendra un jour où, **$[...]** ne sera plus. |
- | echo $c # réponse 12 | + | </note> |
- | d=$(( 10 / 3 )) | + | |
- | echo $d # réponse 3 | + | ===== Les systèmes numériques ===== |
- | e=$(( 10 % 3 )) | + | |
- | echo $e # réponse 1 | + | Les expressions numériques évaluées par **let** et **<nowiki>((...))</nowiki>** peuvent contenir des nombres de différents systèmes numérique.\\ |
+ | |||
+ | L'évaluation des expression (le résultat) sera toujours retourné en entier décimal. | ||
+ | |||
+ | * Sans précision les nombres sont en base 10 (décimal). | ||
+ | * Préfixé d'un **0**, le nombre est un octal (base 8). | ||
+ | * Préfixé de **0x** (ou **0X**), le nombre est un hexadécimal (base 16). | ||
+ | |||
+ | Si non, la syntaxe suivante peut-être utilisée : | ||
+ | |||
+ | * [**base#**]**n** | ||
+ | |||
+ | Avec : | ||
+ | |||
+ | * **base#** où **base** est un nombre en décimal désignant la base utilisée (de 2 à 64). | ||
+ | * **n** Le nombre lui même : | ||
+ | * Jusqu'à la base 10, le nombre contient que des chiffres. | ||
+ | * De la base 11 à la base 36, les lettres minuscules ou majuscules peuvent être utilisées indifféremment. | ||
+ | * De la base 37 à la base 64, les lettres minuscules, majuscules, @ et _ sont à utiliser dans cet ordre. | ||
+ | ===== Les opérateurs arithmétiques ===== | ||
+ | |||
+ | Les opérateurs arithmétiques permettent de réaliser des calculs numériques classiques. | ||
+ | |||
+ | | Liste des opérateurs arithmétiques ||| | ||
+ | ^ Opérateurs ^ Désignations ^ Résultats ^ | ||
+ | | Opérateurs unaires ||| | ||
+ | | **''+''** //expr// | Signe positif | Valeur de //expr// | | ||
+ | | **''-''** //expr// | Signe négatif | Opposé de //expr// | | ||
+ | | Opérateurs binaires ||| | ||
+ | | //expr1// **''+''** //expr2// | Addition | //expr2// ajouté à //expr1// | | ||
+ | | //expr1// **''-''** //expr2// | Soustraction | //expr2// retiré de //expr1// | | ||
+ | | //expr1// **''*''** //expr2// | Multiplication| //expr1// multiplié par //expr2// | | ||
+ | | //expr1// **''/''** //expr2// | Division | //expr1// divisé par //expr2// | | ||
+ | | //expr1// **''%''** //expr2// | Modulo | Reste de la division de //expr1// par //expr2// | | ||
+ | | //expr1// **''<nowiki>**</nowiki>''** //expr2//| Puissance | //expr1// multiplié par lui-même //expr2// fois | | ||
+ | |||
+ | Exemples : | ||
+ | |||
+ | <code user> | ||
+ | a=42 # Affecte 42 à la variable a | ||
+ | echo $((-a)) # Retourne l'opposé de la valeur contenue dans la variable a. | ||
+ | |||
+ | echo $((21+025)) # Retourne l’addition de l'octal 25 au décimal 21. | ||
+ | |||
+ | echo 3/2=$((3/2)) # Retourne 3/2 | ||
+ | echo 3/2 reste $((3%2)) # Retourne le reste de 3/2 | ||
+ | |||
+ | echo a=$a a^2=$((a**2)) # Retourne la valeur de la variable élevée à la puissance 2 | ||
+ | |||
+ | unset a | ||
+ | </code><code> | ||
+ | -42 | ||
+ | 42 | ||
+ | 3/2=1 | ||
+ | 3/2 reste 1 | ||
+ | a=42 a^2=1764 | ||
</code> | </code> | ||
- | ====2) avec la commande let (les signes mathématiques ont la même fonction) :==== | + | <note important> |
- | <code> | + | La division par 0 retourne une erreur.\\ |
- | #!/bin/bash | + | \\ |
- | let "a = 5" | + | <code user> |
- | let "b = 10" | + | echo $((42/0)) |
- | let "c = a + b" | + | </code><code> |
- | let "e= a * b" | + | bash: 42/0 : division par 0 (le symbole erroné est « 0 ») |
- | let "f= b / a" | + | </code> |
- | let "g= b % a" | + | </note> |
- | echo -e "$c \n$e \n$f \n$g" # ou /bin/echo "$c $e $f $g" | + | |
- | # réponse : | + | ===== Les opérateurs d'affectation ===== |
- | 15 | + | |
- | 50 | + | Les opérateurs d'affectation, permettent affecter une valeur à une variable ou d'en modifier la valeur. |
- | 2 | + | |
+ | | Liste des opérateurs d'affectation ||| | ||
+ | ^ Opérateurs ^ Désignations ^ Résultats ^ | ||
+ | | Opérateurs unaires ||| | ||
+ | | **''++''** //var// | Affectation par la pré-incrémentation à 1 | //var// = //var// + 1 puis retourne //var// | | ||
+ | | //var// **''++''** | Affectation par la post-incrémentation à 1 | Retourne //var//, puis //var// = //var// + 1 | | ||
+ | | **''--''** //var// | Affectation par la pré-décrémentation à 1 | //var// = //var// - 1 puis retourne //var// | | ||
+ | | //var// **''--''** | Affectation par la post-décrémentation à 1 | Retourne //var//, puis //var// = //var// - 1 | | ||
+ | | Opérateurs binaires ||| | ||
+ | | //var// **''=''** //expr// | Simple affectation | Affecte //epxr// à la variable //var// | | ||
+ | | //var// **''+=''** //expr// | Affectation par l'incrémentation | //var// = //var// + //expr// | | ||
+ | | //var// **''-=''** //expr// | Affectation par la décrémentation | //var// = //var// - //expr// | | ||
+ | | //var// **''*=''** //expr// | Affectation par la multiplication | //var// = //var// * //expr// | | ||
+ | | //var// **''/=''** //expr// | Affectation par la division | //var// = //var// / //expr// | | ||
+ | | //var// **''%=''** //expr// | Affectation par modulo | //var// = //var// % //expr// | | ||
+ | | //var// **''<nowiki><<=</nowiki>''** //expr// | Ré-affectation par le décalage\\ bit-à-bit à gauche | //var// = //var// <nowiki><<</nowiki> //expr// | | ||
+ | | //var// **''<nowiki>>>=</nowiki>''** //expr// | Ré-affectation par le décalage\\ bit-à-bit à droite | //var// = //var// <nowiki>>></nowiki> //expr// | | ||
+ | | //var// **''&=''** //expr// | Affectation par le ET binaire | //var// = //var// <nowiki>&</nowiki> //expr// | | ||
+ | | //var// **''|=''** //expr// | Affectation par le OU binaire | //var// = //var// <nowiki>|</nowiki> //expr// | | ||
+ | | //var// **''^=''** //expr// | Affectation par le OU exclusif binaire | //var// = //var// <nowiki>^</nowiki> //expr// | | ||
+ | |||
+ | Exemples : | ||
+ | |||
+ | <code user> | ||
+ | declare -p a | ||
+ | let a=24 ; declare -p a | ||
+ | ((a=42)) ; echo a=$a | ||
+ | |||
+ | let 'a += 42' ; echo "a+=42 -> a=$a" | ||
+ | (( a /= 2 )) ; echo "a/=2 -> a=$a" | ||
+ | |||
+ | unset a | ||
+ | </code><code> | ||
+ | bash: declare: a : non trouvé | ||
+ | declare -- a="24" | ||
+ | a=42 | ||
+ | a+=42 -> a=84 | ||
+ | a/=2 -> a=42 | ||
+ | </code> | ||
+ | |||
+ | <note> | ||
+ | Contrairement à la commande **declare -i**, les commandes **let** et **<nowiki>((..))</nowiki>** ne donnent pas l'attribut numérique (**-i**) à une variable. | ||
+ | </note> | ||
+ | |||
+ | <code user> | ||
+ | declare -i b=42 | ||
+ | declare -p b | ||
+ | echo "Pré-incrémentation à 1 : Avant b=$b ; Pendant b=$((++b)) ; Après : b=$b" | ||
+ | echo "Post-décrémentation à 1 : Avant b=$b ; Pendant b=$((b--)) ; Après : b=$b" | ||
+ | |||
+ | unset b | ||
+ | </code><code> | ||
+ | declare -i b="42" | ||
+ | Pré-incrémentation à 1 : Avant b=42 ; Pendant b=43 ; Après : b=43 | ||
+ | Post-décrémentation à 1 : Avant b=43 ; Pendant b=43 ; Après : b=42 | ||
+ | </code> | ||
+ | |||
+ | Voir aussi : | ||
+ | * **[[doc:programmation:shells:script-bash-variables-arguments-parametres?&#typologie-des-variables|typologie de variables]]** | ||
+ | * **[[doc:programmation:shells:script-bash-variables-arguments-parametres?&#variables-numeriques-et-calculs|variables numériques et calculs]]** | ||
+ | |||
+ | ===== L'opérateur virgule ===== | ||
+ | |||
+ | L'opérateur virgule, permet de séparer des opérations. | ||
+ | |||
+ | | L'opérateur virgule ||| | ||
+ | ^ Opérateur ^ Désignation ^ Résultat ^ | ||
+ | |Opérateur binaire ||| | ||
+ | | //expr1// **'',''** //expr2// | Virgule | Sépare les opération //expr1// et //expr2// pour les réaliser à la suite. | | ||
+ | |||
+ | Exemples : | ||
+ | |||
+ | <code user> | ||
+ | echo $(( 5+5 , 10+5 , 21+21)) | ||
+ | </code><code> | ||
+ | 42 | ||
+ | </code> | ||
+ | Seule la dernière opération est retournée. | ||
+ | |||
+ | C'est plus utile avec des affectations : | ||
+ | <code user> | ||
+ | echo $(( a=5+5 , b=10+5 , 21+21)) | ||
+ | echo a=$a b=$b | ||
+ | unset a b | ||
+ | </code><code> | ||
+ | 42 | ||
+ | a=10 b=15 | ||
+ | </code> | ||
+ | ===== Les opérateurs logiques ===== | ||
+ | |||
+ | Les opérateurs logiques, réalisent des opérations sur des booléens.\\ | ||
+ | L'algèbre de boole n'énumère que deux états : **vrai** et **faux**.\\ | ||
+ | Les commandes **let** et **<nowiki>((..))</nowiki>** suivent le standard C : | ||
+ | |||
+ | * **0** est compris comme **faux**. | ||
+ | * Toutes autres valeurs (positives ou négatives), souvent **1**, sont comprises comme **vrai**. | ||
+ | |||
+ | ... Dans bash, c'est le contraire (voir la note plus bas). | ||
+ | |||
+ | Trois opérateurs logiques sont disponibles : 1 unaire et 2 binaires. | ||
+ | |||
+ | <note important>Les opérateurs logiques ne doivent être confondus avec les opérateurs bit-à-bit.</note> | ||
+ | |||
+ | | Liste des opérateurs logiques ||| | ||
+ | ^ Opérateurs ^ Désignations ^ Résultats ^ | ||
+ | | Opérateur unaire ||| | ||
+ | | **''!(''** //expr// **'')''** | Négation logique | Retourne l'inverse de //expr//\\ !(1) = 0 (NON vrai = faux)\\ !(0) = 1 (NON faux = vrai)| | ||
+ | | Opérateurs binaires ||| | ||
+ | | //expr1// **''<nowiki>&&</nowiki>''** //expr2// | ET logique | 1 <nowiki>&&</nowiki> 1 = 1 (vrai ET vrai = vrai)\\ 1 <nowiki>&&</nowiki> 0 = 0 (vrai ET faux = faux)\\ 0 <nowiki>&&</nowiki> 1 = 0 (faux ET vrai = faux)\\ 1 <nowiki>&&</nowiki> 1 = 0 (faux ET faux = faux) | | ||
+ | | //expr1// **''<nowiki>||</nowiki>''** //expr2// | OU logique | 1 <nowiki>&&</nowiki> 1 = 1 (vrai OU vrai = vrai)\\ 1 <nowiki>&&</nowiki> 0 = 1 (vrai OU faux = vrai)\\ 0 <nowiki>&&</nowiki> 1 = 1 (faux OU vrai = vrai)\\ 0 <nowiki>&&</nowiki> 0 = 0 (faux OU faux = faux) | | ||
+ | | //epr//, //expr1//, //expr2// sont sujets aux développements||| | ||
+ | |||
+ | Exemples : | ||
+ | |||
+ | <code user> | ||
+ | echo "!(0) = $((!(0)))" | ||
+ | echo "!(5+5) = $((!(5+5)))" | ||
+ | echo $((!1)) | ||
+ | </code><code> | ||
+ | !(0) = 1 | ||
+ | !(5+5) = 0 | ||
+ | bash: !1: event not found | ||
+ | </code> | ||
+ | |||
+ | <note>L'opérateur de négation logique **!**) s'utilise uniquement avec des parenthèses : **!(//expr//)**.</note> | ||
+ | |||
+ | Les opérations logiques peuvent se suivre : | ||
+ | |||
+ | <code user> | ||
+ | echo $(( 1 && 1)) | ||
+ | echo $(( 1 && 0)) | ||
+ | echo $(( 1 && 1 && 0)) # vrai && vrai && faux, retourne faux | ||
+ | </code><code> | ||
+ | 1 | ||
+ | 0 | ||
0 | 0 | ||
- | # bashisme de l'option -e pour forcer le retour à la ligne pour chaque appel de valeur $c $e $f $g | ||
- | # réponse : 15 50 2 0 | ||
</code> | </code> | ||
- | ====3) écriture proche de c :==== | + | Les opérateurs **<nowiki>&&</nowiki>** et **<nowiki>||</nowiki>** n'étudient l'opérande de droite (//expr2//) que si cela est pertinent : |
- | <code> | + | |
- | let "a = 5" | + | <code user> |
- | let "b = 10" | + | a=1 |
- | let "c = a *= 3" | + | echo $((0 && (a=10) )) a=$a # Le second opérande (a=10) n'est pas étudié car cela n'est pas pertinent |
- | let "d = a += 3" # valeur précédente de a conservée pour calculer d : 15+3 =18 | + | # avec 0 (faux) et l'opérateur &&, le résultat sera toujours faux. |
- | let "e = b /= 3" | + | |
- | let "f = b /= 3" # valeur précédente de b conservée pour calculer f : 3/3 =1 | + | echo $((1 && (a=10) )) a=$a # Le second opérande (a=10) est étudié car cela est pertinent |
- | echo "c=$c d=$d e=$e f=$f" # réponse : c=15 d=18 e=3 f=1 | + | # avec 1 (vrai) et l'opérateur &&, le résultat pourra être vrai. |
- | i=1 | + | unset a |
- | let "i += 7" | + | </code><code> |
- | echo "i=$i" # réponse : i=8 | + | 0 a=1 |
- | j=4 | + | 1 a=10 |
- | let "j *= 5" | + | |
- | echo "j=$j" # réponse : j=20 | + | |
</code> | </code> | ||
- | ====4) écriture utile pour les boucles : ==== | + | <note>Nous avons placé l'affection **a=10** entre parenthèses **(a=10)**, pour la protéger contre la priorité des opérateurs.\\ |
- | * **post-incrémentation avec conservation de la la valeur et idem pour pré-incrémentation :** | + | \\ |
+ | Sinon, l'opérateur **<nowiki>&&</nowiki>** étant prioritaire à l'opérateur d'affectation **=**, les opérations effectuées deviennent **<nowiki>0 && a</nowiki>**, puis **=10**, ce qui génère une erreur. | ||
+ | \\ | ||
+ | <code user> | ||
+ | echo $((1 && a=10 )) a=$a | ||
+ | </code><code> | ||
+ | bash: 0 && a=10 : tentative d'affectation à une non-variable (le symbole erroné est « =10 ») | ||
+ | </code> | ||
- | <code> | + | Voir plus bas [[doc:programmation:shells:page-man-bash-iv-symboles-dans-les-calculs-mathematiques#priorités-des-operateurs|les priorités des opérateurs]]. |
+ | </note> | ||
+ | |||
+ | S'il n'est pas pertinent d'étudier l'opérande de droite et qu'il existe d'autres opérateurs, alors les opérations se poursuivent. | ||
+ | |||
+ | <code user> | ||
+ | a=0 | ||
+ | echo $((a && (a=10) || (a=20) )) a=$a # Avec a=0 (faux) et l'opérateur &&, il n'est pas pertinent d'étudier le second opérande | ||
+ | # L'opération se reporte sur l'opérateur ||, étant pertinent, son opérande de droite est étudié. | ||
+ | a=1 | ||
+ | echo $((a && (a=10) || (a=20) )) a=$a | ||
+ | unset a | ||
+ | </code><code> | ||
+ | 1 a=20 | ||
+ | 1 a=10 | ||
+ | </code> | ||
+ | |||
+ | <note important> | ||
+ | Les opérations logiques retournent une valeur booléenne.\\ | ||
+ | \\ | ||
+ | Les commandes **let** et **<nowiki>((..))</nowiki>** suivent le standard C.\\ | ||
+ | Elles numérisent **faux** avec **0** et **vrai** avec une valeur **non nulle**.\\ | ||
+ | \\ | ||
+ | Avec bash c'est l'inverse, **faux** est une valeur **non nulle** et **vrai** correspond à **0**.\\ | ||
+ | \\ | ||
+ | Il en résulte que le code retour renvoyé est l'inverse du résultat des opérations logiques effectuées par **let** ou **<nowiki>((..))</nowiki>** | ||
+ | <code user> | ||
+ | echo $(( !(0) )) | ||
+ | (( !(0) )); echo $? | ||
+ | </code><code> | ||
+ | 1 | ||
+ | 0 | ||
+ | </code> | ||
+ | </note> | ||
+ | |||
+ | ===== Les opérateurs relationnels ===== | ||
+ | |||
+ | Les opérateurs relationnels permettent la comparaison entre deux epressions numériques.\\ | ||
+ | Voir [[doc:programmation:shells:page-man-bash-iii-les-operateurs-de-comparaison-numerique#comparaison-numerique-avec|Comparaison numérique avec ((...))]] | ||
+ | |||
+ | <note important> | ||
+ | Comme avec les opérateurs logiques, le résultat des comparaisons des opérateurs relationnels retourne une valeur booléenne.\\ | ||
+ | (**vrai** en cas de succès **faux** en cas d'échec).\\ | ||
+ | \\ | ||
+ | Le code de retour renvoyé est donc contraire au résultat des comparaisons effectuées par **let** ou **<nowiki>((..))</nowiki>** | ||
+ | <code user> | ||
+ | echo $((24<42)) | ||
+ | ((24<42)); echo $? | ||
+ | </code><code> | ||
+ | 1 | ||
+ | 0 | ||
+ | </code> | ||
+ | </note> | ||
+ | ===== Les opérateurs bit-à-bit ===== | ||
+ | |||
+ | Les opérateurs bit-bit, opèrent sur des nombres binaires (une suite de 0 ou de 1).\\ | ||
+ | Les nombres sont d'abord convertis en binaire, l’opération est appliquée, puis le résultat est reconverti en décimal. | ||
+ | |||
+ | <note important>Les opérateurs bit-à-bit ne doivent pas être confondus avec les opérateurs logiques</note> | ||
+ | |||
+ | | Liste des opérateurs bit-à-bit ||| | ||
+ | ^ Opérateurs ^ Désignations ^ Résultats ^ | ||
+ | | Opérateur unaire ||| | ||
+ | | **''~''** //expr// | Négation binaire | Renvoie le complément à 1 de //expr//\\ (~1 -> 0 ; ~0 -> 1) | | ||
+ | | Opérateurs binaires ||| | ||
+ | | //expr1// **''&''** //expr2// | ET binaire | Renvoie le ET bit-à-bit entre //expr1// et //expr2//\\ (1 ET 1 -> 1 ; 0 ET 0 -> 0 ; 1 ET 0 -> 0 ; 0 ET 1 -> 0) | | ||
+ | | //expr1// **''|''** //expr2// | OU binaire | Renvoie le OU bit-à-bit entre //expr1// et //expr2//\\ (1 OU 1 -> 1 ; 0 OU 0 -> 0 ; 1 OU 0 -> 1 ; 0 OU 1 -> 1) | | ||
+ | | //expr1// **''^''** //expr2// | OU binaire exclusif (XOR) | Renvoie le OU bit-à-bit exclusif entre //expr1// et //expr2//\\ (1 XOR 1 -> 0 ; 0 XOR 0 -> 0 ; 1 XOR 0 -> 1 ; 0 XOR 1 -> 1) | | ||
+ | | //expr1// **''<nowiki><<</nowiki>''** //expr2//| Décalage binaire à gauche | Renvoie le décalage de //expr2// bit(s) à gauche de //expr1//\\ (//expr2// 0 ajoutés(s) à droite d'//expr1//) | | ||
+ | | //expr1// **''<nowiki>>></nowiki>''** //expr2//| Décalage binaire à droite | Renvoie le décalage de //expr2// bit(s) à droite de //expr1//\\ (//expr2// bit(s) tronqué(s) à droite d'//expr1//) | | ||
+ | | //epr//, //expr1//, //expr2// sont sujets aux développements||| | ||
+ | |||
+ | Exemples | ||
+ | <code user> | ||
+ | echo $((~42)) | ||
+ | echo $((42^42)) | ||
+ | echo $((42<<2)) | ||
+ | </code><code> | ||
+ | -43 | ||
+ | 0 | ||
+ | 168 | ||
+ | </code> | ||
+ | |||
+ | Voir aussi : | ||
+ | |||
+ | * [[atelier:chantier:bash:operations-les-nombres-binaires|Opérations sur les nombres binaires]] | ||
+ | |||
+ | ===== Les opérateurs conditionnels ===== | ||
+ | |||
+ | Les opérateurs conditionnels permettent de réaliser des opérations sous conditions.\\ | ||
+ | Les opérations sélectionnées sont déterminées selon une structure, **si** ... **alors** ... **sinon** ..., mais en plus succin. | ||
+ | |||
+ | | Les opérateurs conditionnels ||| | ||
+ | ^ opérateurs ^ Désignations ^ Explications ^ | ||
+ | | //expr1// **''?''** //expr2// **'':''** //expr3// | Opérateur\\ conditionnel | //epxr1// est comprise comme un booléen : **Vrai** (**!=0**) ou **faux** (**=0**)\\ Si //expr1// est vrai **''?''** (alors) //expr2// **'':''** (sinon) //expr3//. | | ||
+ | | //expr1//, //expr2// et //expr3//, sont sujettes au remplacement des paramètres (et des variables), à la substitution de commandes et à la suppression des protections. ||| | ||
+ | |||
+ | Exemples : | ||
+ | |||
+ | <code user> | ||
+ | echo $((24<42 ? 5 : 10 )) | ||
+ | let "24>42 ? (a=5) : (a=10)" | ||
+ | echo $a | ||
+ | |||
+ | unset a | ||
+ | </code><code> | ||
+ | 5 | ||
+ | 10 | ||
+ | </code> | ||
+ | |||
+ | Les conditions peuvent s'imbriquer : | ||
+ | |||
+ | <code user> | ||
+ | a=42 b=10 | ||
+ | echo $((a ? b > 0 ? 100 : -100 : 24 )) | ||
+ | b=-10 | ||
+ | echo $((a ? b > 0 ? 100 : -100 : 24 )) | ||
+ | a=0 | ||
+ | echo $((a ? b > 0 ? 100 : -100 : 24 )) | ||
+ | |||
+ | unset a b | ||
+ | </code><code> | ||
+ | 100 | ||
+ | -100 | ||
+ | 24 | ||
+ | </code> | ||
+ | |||
+ | Cela risque rapidement de devenir illisible, pour plus de clarté, nous pouvons utiliser des parenthèses. | ||
+ | |||
+ | <code user> | ||
+ | echo $((24<42 ? (b > 0 ? 100 :-100) : 24 )) | ||
+ | </code><code> | ||
+ | 24 | ||
+ | </code> | ||
+ | |||
+ | <note important> | ||
+ | Les opérateurs conditionnels sont deux et ne peuvent s'utiliser seuls.\\ | ||
+ | \\ | ||
+ | <code user> | ||
+ | ((24<42 ? 5)) | ||
+ | echo $? | ||
+ | ((24<42 : 5)) | ||
+ | echo $? | ||
+ | </code><code> | ||
+ | bash: ((: 24<42 ? 5 : « : » attendu pour une expression conditionnelle (le symbole erroné est « 5 ») | ||
+ | 1 | ||
+ | bash: ((: 24<42 : 5 : erreur de syntaxe dans l'expression (le symbole erroné est « : 5 ») | ||
+ | 1 | ||
+ | </code> | ||
+ | </note> | ||
+ | |||
+ | ===== Priorités des opérateurs ===== | ||
+ | |||
+ | La priorité des opérateurs précise l'ordre dans lequel les opérations sont effectués dans une expression complexe.\\ | ||
+ | L'associativité permet de définir l'ordre des opérations pour les opérateurs de même priorité.\\ | ||
+ | La priorité et l'associativité des opérateurs des commande **let** et **<nowiki>((...))</nowiki>** sont identique au langage C. | ||
+ | |||
+ | | Priorités et associativité des opérateurs ||| | ||
+ | ^ Opérateurs ^ Désignations ^ Associativités ^ | ||
+ | | Les priorités sont classé ci-dessous par ordre décroissant.\\ Sur une même ligne, les opérateurs ont même priorité. ||| | ||
+ | | **''(''**...**'')''** | Parenthèses || | ||
+ | | expr**''++''** expr**''--''** | Post-incrément et post-décrément de variables | -> | | ||
+ | | **''-''** **''+''** | Moins et plus unaires | <- | | ||
+ | | **''++''**expr **''--''**expr | Pré-incrément et pré-décrément de variables | <- | | ||
+ | | **''!''** **''~''** | Négations logique et binaire | <- | | ||
+ | | **''<nowiki>**</nowiki>''** | Exponentiation (puissance) | | | ||
+ | | **''*''** **''/''** **''%''** | Multiplication, division, modulo | -> | | ||
+ | | **''+''** **''-''** | Addition, soustraction | -> | | ||
+ | | **''<nowiki><<</nowiki>''** **''<nowiki>>></nowiki>''** | Décalage arithmétique à gauche et à droite | -> | | ||
+ | | **''<nowiki><=</nowiki>''** **''<nowiki>>=</nowiki>''** **''<''** ***''>''** | Relationnels | -> | | ||
+ | | **''<nowiki>==</nowiki>''** **''<nowiki>!=</nowiki>''** | Egalité et différence | -> | | ||
+ | | **''&''** | ET binaire | -> | | ||
+ | | **''<nowiki>^</nowiki>''** | OU exclusif binaire | -> | | ||
+ | | **''<nowiki>|</nowiki>''** | OU binaire | -> | | ||
+ | | **''<nowiki>&&</nowiki>''** | ET logique | -> | | ||
+ | | **''<nowiki>||</nowiki>''** | OU logique | -> | | ||
+ | | **''?''** **'':''** | Opérateur conditionnel | <- | | ||
+ | | **''=''** **''<nowiki>*=</nowiki>''** **''<nowiki>/=</nowiki>''** **''<nowiki>%=</nowiki>''** **''<nowiki>+=</nowiki>''** **''<nowiki>-=</nowiki>''** **''<nowiki><<=</nowiki>''** **''<nowiki>>>=</nowiki>''** **''<nowiki>&=</nowiki>''** **''<nowiki>^=</nowiki>''** **''<nowiki>|=</nowiki>''** | Affectations | <- | | ||
+ | | **'',''** | Virgule | -> | | ||
+ | | Sources : Les priorités proviennent de page du manuel de bash (section ÉVALUATION ARITHMÉTIQUE), les associativités du C. ||| | ||
+ | |||
+ | |||
+ | Les parenthèses ont la priorité la plus haute, elles permettent d'outre passer toutes les autres. | ||
+ | |||
+ | Exemples : | ||
+ | |||
+ | <code user> | ||
+ | echo $(( 18 + 3 * 2 )) | ||
+ | |||
+ | echo $(( (18 + 3) * 2 )) | ||
+ | </code><code> | ||
+ | 24 | ||
+ | 42 | ||
+ | </code> | ||
+ | ===== Écriture utile pour les boucles ===== | ||
+ | ===Post-incrémentation et pré-incrémentation :=== | ||
+ | |||
+ | <code bash script> | ||
#!/bin/bash | #!/bin/bash | ||
declare -i x=20 y # ici les signes = permettent une affection | declare -i x=20 y # ici les signes = permettent une affection | ||
(( y = x++ )) # d'abord la valeur de x est conservée dans la valeur de y (donc $y= 20) puis la valeur | (( y = x++ )) # d'abord la valeur de x est conservée dans la valeur de y (donc $y= 20) puis la valeur | ||
- | # de x est incrémenté ($x est donc égal à 21) | + | # de x est incrémentée ($x est donc égal à 21) |
# les espaces autour du signe = ne sont pas obligatoires | # les espaces autour du signe = ne sont pas obligatoires | ||
echo "y=$y x=$x" # réponse : y=20 x=21 | echo "y=$y x=$x" # réponse : y=20 x=21 | ||
</code> | </code> | ||
- | <code> | + | <code bash script> |
#!/bin/bash | #!/bin/bash | ||
declare -i x=20 y | declare -i x=20 y | ||
(( y = ++x )) # d'abord la valeur de x est incrémentée puis la valeur de y reçoit | (( y = ++x )) # d'abord la valeur de x est incrémentée puis la valeur de y reçoit | ||
- | # la valeur du x incrémentée | + | # la valeur du x incrémenté |
# les espaces autour du signe = ne sont pas obligatoires | # les espaces autour du signe = ne sont pas obligatoires | ||
echo "y=$y x=$x" # réponse : y=21 x=21 | echo "y=$y x=$x" # réponse : y=21 x=21 | ||
</code> | </code> | ||
- | * **post-décrémentation avec conservation de la la valeur et idem pour pré-décrémentation :** | + | ===Post-décrémentation et pré-décrémentation :=== |
- | <code> | + | <code bash script> |
#!/bin/bash | #!/bin/bash | ||
declare -i x=20 y | declare -i x=20 y | ||
(( y = x-- )) # d'abord la valeur de x est conservée dans la valeur de y (donc $y= 20) | (( y = x-- )) # d'abord la valeur de x est conservée dans la valeur de y (donc $y= 20) | ||
- | # puis la valeur de x est décrémenté ($x est donc égal à 19) | + | # puis la valeur de x est décrémentée ($x est donc égal à 19) |
# les espaces autour du signe = ne sont pas obligatoires | # les espaces autour du signe = ne sont pas obligatoires | ||
echo "y=$y x=$x" # réponse : y=20 x=19 | echo "y=$y x=$x" # réponse : y=20 x=19 | ||
</code> | </code> | ||
- | <code> | + | <code bash script> |
#!/bin/bash | #!/bin/bash | ||
declare -i x=20 y | declare -i x=20 y | ||
(( y = --x )) # d'abord la valeur de x est décrémentée ($x=19), puis la valeur de y | (( y = --x )) # d'abord la valeur de x est décrémentée ($x=19), puis la valeur de y | ||
- | # reçoit la valeur du x incrémentée (donc $y=19) | + | # reçoit la valeur du x incrémenté (donc $y=19) |
# les espaces autour du signe = ne sont pas obligatoires | # les espaces autour du signe = ne sont pas obligatoires | ||
echo "y=$y x=$x" # réponse : y=19 x=19 | echo "y=$y x=$x" # réponse : y=19 x=19 | ||
</code> | </code> | ||
+ | <note tip> | ||
+ | En bref,\\ | ||
+ | __**Post-incrémentation/décrémentation**__ : Les signes d'incrémentation (**''++''**) ou de décrémentation (**''<nowiki>--</nowiki>''**) sont placés **après** une valeur à incrémenter (+1) ou à décrémenter (-1) ; cette valeur est conservée dans "y" puis elle est **incrémentée (+1)** ou **décrémentée (-1)**.\\ | ||
+ | |||
+ | __**Pré-incrémentation/décrémentation**__ : Les signes d'incrémentation (**''++''**) ou de décrémentation (**''<nowiki>--</nowiki>''**) sont placés **avant** une valeur à incrémenter ou à décrémenter ; cette valeur est **incrémentée (+1)** ou **décrémentée (-1)** puis elle est conservée dans "y". | ||
+ | </note> | ||
+ | =====Tuto précédent ===== | ||
- | ===La suite, c'est ici : === | + | [[doc:programmation:shells:page-man-bash-iii-les-operateurs-de-comparaison-numerique|Bash : les opérateurs de comparaison numérique]] |
- | [[atelier:chantier:page-man-bash-v-les-tableaux]] | + | |
- | ===tuto précédent :=== | + | =====La suite, c'est ici ===== |
- | [[atelier:chantier:page-man-bash-iii-les-operateurs-de-comparaison-numerique?&#operateurs-de-comparaison-numerique]] | + | [[doc:programmation:shells:page-man-bash-v-les-tableaux|Bash : les tableaux]] |