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-iii-les-operateurs-de-comparaison-numerique [15/02/2023 12:36] agp91 [Comparaison numérique avec [ et [[] |
doc:programmation:shells:page-man-bash-iii-les-operateurs-de-comparaison-numerique [15/02/2023 18:51] agp91 [Comparaison numérique avec ((] |
||
---|---|---|---|
Ligne 24: | Ligne 24: | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | Bash dispose de plusieurs commandes pour réaliser des comparaisons numériques: | + | En interne, bash dispose de plusieurs commandes pour réaliser des comparaisons numériques: |
- | *La commande composée d'évaluation numérique **<nowiki>((</nowiki>**, | + | *La commande composée **<nowiki>((</nowiki>** et la commande **let**. |
- | *La commande **[** (ou **test**), | + | *Les commandes **[** et **test**. |
*Et la commande composée **<nowiki>[[</nowiki>**. | *Et la commande composée **<nowiki>[[</nowiki>**. | ||
+ | |||
+ | Les commandes **[** et **test** sont disponibles dans leurs versions externe : **/usr/bin/[** et **/usr/bin/test**. | ||
__Rappels :__ | __Rappels :__ | ||
Ligne 40: | Ligne 42: | ||
Syntaxe : | Syntaxe : | ||
<code> | <code> | ||
- | (( expr1 OP expr2 )) | + | let <expr1><OP><expr2> |
+ | (( <expr1> <OP> <expr2> )) | ||
- | expr1 et expr2 sont sujets au développement des paramètres et à l’évaluation arithmétique. | + | <expr1> et <expr2> sont sujets au développement des paramètres et à l’évaluation arithmétique. |
- | Avec OP l'un des opérateurs donnés dans le tableau suivant. | + | Avec <OP> l'un des opérateurs donnés dans le tableau suivant. |
+ | Avec la commande let, les opérateurs commençant par < ou > doivent être protégés (voir plus bas : Mauvais usages). | ||
</code> | </code> | ||
+ | __Remarque :__ Les commandes **let** et **<nowiki>((</nowiki>** sont pratiquement équivalentes (voir les différences plus bas Mauvais usages). | ||
- | |Opérateurs de comparaison numérique de la commande <nowiki>((</nowiki> || | + | | Opérateurs de comparaison numérique de la commande <nowiki>((</nowiki> || |
^ Opérateurs ^ Description ^ | ^ Opérateurs ^ Description ^ | ||
| '' == '' | Comparaison d'une égalité | | | '' == '' | Comparaison d'une égalité | | ||
Ligne 55: | Ligne 60: | ||
| '' < '' | Comparaison de plus petit que | | | '' < '' | Comparaison de plus petit que | | ||
| ''<nowiki><=</nowiki> '' | Comparaison de plus petit ou égal que | | | ''<nowiki><=</nowiki> '' | Comparaison de plus petit ou égal que | | ||
- | |||
==== Exemples dans le terminal ==== | ==== Exemples dans le terminal ==== | ||
+ | |||
<code user> | <code user> | ||
(( 42 == 42 )) # Est-ce que 42 est égale à 42. | (( 42 == 42 )) # Est-ce que 42 est égale à 42. | ||
echo $? # Affiche le code de retour. | echo $? # Affiche le code de retour. | ||
+ | let 24\>=24 # Est-ce que 24 est supérieur ou égale à 24 | ||
+ | echo $? # Affiche le code de retour. | ||
+ | </code> | ||
+ | <file config retour des commandes> | ||
+ | 0 | ||
+ | 0 | ||
+ | </file> | ||
+ | <code user> | ||
nombre1=12 | nombre1=12 | ||
nombre2=13 | nombre2=13 | ||
(( $nombre1 > $nombre2 )) # Est-ce-que nombre1 (12) est strictement supérieur au nombre2 (13). | (( $nombre1 > $nombre2 )) # Est-ce-que nombre1 (12) est strictement supérieur au nombre2 (13). | ||
+ | echo $? # Affiche le code de retour. | ||
+ | let $nombre1!=$nombre2 #Est-ce-que nombre1 (12) est différent du nombre2 (13) | ||
echo $? # Affiche le code de retour. | echo $? # Affiche le code de retour. | ||
unset nombre1 nombre2 # Suppression des paramètres nombre1 et nombre2 | unset nombre1 nombre2 # Suppression des paramètres nombre1 et nombre2 | ||
</code> | </code> | ||
- | <file config retour de la commande> | + | <file config retour des commandes> |
- | 0 | + | |
1 | 1 | ||
+ | 0 | ||
</file> | </file> | ||
- | Les paramètres peuvent être transmis sans $ (Sauf les paramètres positionnels et les paramètres spéciaux)\\ | + | Les paramètres peuvent être transmis sans **$** (Sauf les paramètres positionnels et les paramètres spéciaux). |
- | Les espaces peuvent être omis. | + | |
<code user> | <code user> | ||
Ligne 81: | Ligne 95: | ||
n2=24 | n2=24 | ||
(( n1 > n2 )) && echo "$n1 > $n2" || echo "$n1 < $n2" | (( n1 > n2 )) && echo "$n1 > $n2" || echo "$n1 < $n2" | ||
+ | let n1==n2 && echo "$n1 est égale à $n2" || echo "$n1 est différent de $n2" | ||
+ | unset n1 n2 | ||
+ | </code> | ||
+ | <file config retour des commandes> | ||
+ | 42 > 24 | ||
+ | 42 est différent de 24 | ||
+ | </file> | ||
+ | |||
+ | Comme nous l'avons vu au dessus, les paramètre n'ont pas besoin du caractère **$** pour être développé.\\ | ||
+ | Un simple mot sera alors interprété comme un paramètre.\\ | ||
+ | Si ce paramètre n'existe pas, son développent retournera 0. | ||
+ | |||
+ | <code user> | ||
+ | (("mot" == 0)) | ||
+ | echo '(("mot" == 0)) revoie le code de retour' $? | ||
+ | let mot\<=0 | ||
+ | echo 'let "mot"\<=0 revoie le code de retour' $? | ||
+ | |||
+ | n="mot" | ||
+ | ((n!=0)) | ||
+ | echo -e "Avec n=\"$n\" ; ((n!=0)) renvoie le code de retour $?" | ||
+ | let n==0 | ||
+ | echo -e "Avec n=\"${n}\" ; let n==0 renvoie le code de retour $?" | ||
+ | |||
+ | unset n | ||
+ | </code> | ||
+ | <file config retour des commandes> | ||
+ | (("mot" == 0)) revoie le code de retour 0 | ||
+ | let "mot"\<=0 revoie le code de retour 0 | ||
+ | Avec n="mot" ; ((n!=0)) renvoie le code de retour 1 | ||
+ | Avec n="mot" ; let n==0 renvoie le code de retour 0 | ||
+ | </file> | ||
+ | |||
+ | Avec la commande **<nowiki>((</nowiki>**, les espaces ne sont pas obligatoires. | ||
+ | <code user> | ||
+ | n1=4242 | ||
+ | n2=2424 | ||
if ((n1>n2)) | if ((n1>n2)) | ||
then | then | ||
Ligne 92: | Ligne 143: | ||
</code> | </code> | ||
<file config retour de la commande> | <file config retour de la commande> | ||
- | 42 > 24 | + | 4242 est supérieur à 2424 |
- | 42 est supérieur à 24 | + | |
</file> | </file> | ||
- | Le développement des opérandes doivent être des valeurs numériques.\\ | + | ==== Mauvais usages ==== |
- | Mais comme nous l'avons vu au dessus, les paramètre n'ont pas besoin du caractère $ pour être développé.\\ | + | |
- | Un simple mot sera alors interprété comme un paramètre.\\ | + | |
- | Si ce paramètre n'existe pas, son développent retournera 0. | + | |
- | __Rappel :__ L'option -e de la commande echo permet de développer les caractères protégés, (ici \n qui se développe en saut de ligne).\\ | + | La commande **let** ne supporte pas les espaces entre les opérandes et l'opérateur. |
- | Le développement des caractères protégés se réalisent entre guillemets doubles.\\ | + | |
- | Sans guillemets, il est nécessaire de protégé le caractère de protection (\\n). | + | |
<code user> | <code user> | ||
- | echo ========== | + | let -42 \< 0 ; echo $? |
- | (("Du texte" >= 0)) | + | let 0 == 0 ; echo $? |
- | echo -e "((\"Du texte\" >= 0)) revoie le code de retour $? \n" | + | </code> |
+ | <file config retour des commandes> | ||
+ | bash: let: < : erreur de syntaxe : opérande attendu (le symbole erroné est « < ») | ||
+ | 1 | ||
+ | bash: let: == : erreur de syntaxe : opérande attendu (le symbole erroné est « == ») | ||
+ | 1 | ||
+ | </file> | ||
- | (("DuTexte" == 0)) | + | Avec la commande **let**, les opérateurs **<**, **<nowiki><=</nowiki>**, **>** et **>=** doivent être protégés.\\ |
- | echo -e "((\"DuTexte\" == 0)) revoie le code de retour $? \n" | + | |
- | n="Du texte" | + | Les trois types de protection (**\**, entre guillemets simples **<nowiki>''</nowiki>** et entre guillemets double **""** fonctionnent.\\ |
- | ((n>=0)) | + | S'ils ne sont pas protégés, les opérateurs **<** et **>** sont des opérateurs de redirection.\\ |
- | echo -e 'Avec n="Du texte" ; ((n>=0)) renvoie le code retour' $? \\n | + | Démonstration : |
- | n="Dutexte" | + | __Rappels :__\\ |
- | ((n!=0)) | + | La commande **printf "\n"**, retourne un saut de ligne.\\ |
- | echo -e 'Avec n="DuTexte" ; ((n!=0)) renvoie le code retour' $? \\n | + | La commande **echo -n**, n'ajoute pas de saut ligne à la fin de son retour. |
- | unset n | + | <code user> |
+ | p=$PWD | ||
+ | mkdir /tmp/test_let | ||
+ | cd /tmp/test_let | ||
+ | |||
+ | let 240>420 ; echo $? | ||
+ | let 241>=421 ; echo $? | ||
+ | let 243<423 ; echo $? | ||
+ | let 244<=424 ; echo $? | ||
+ | |||
+ | printf "\n" | ||
+ | echo -n "ls :" | ||
+ | ls | ||
+ | printf "\n" | ||
+ | |||
+ | cd $p | ||
+ | rm -rfv /tmp/test_let | ||
</code> | </code> | ||
<file config retour des commandes> | <file config retour des commandes> | ||
- | ========== | + | bash: let: une expression est attendue |
+ | 1 | ||
+ | bash: let: une expression est attendue | ||
+ | 1 | ||
+ | bash: 423: Aucun fichier ou dossier de ce type | ||
+ | 1 | ||
+ | bash: =424: Aucun fichier ou dossier de ce type | ||
+ | 1 | ||
+ | |||
+ | ls : 420 '=421' | ||
+ | |||
+ | '/tmp/test_let/=421' supprimé | ||
+ | '/tmp/test_let/420' supprimé | ||
+ | répertoire '/tmp/test_let' supprimé | ||
+ | </file> | ||
+ | |||
+ | Les opérateurs **>** et **>=** ont créé respectivement les fichiers **420** et **=421**.\\ | ||
+ | Les opérateurs **<** et **<nowiki><=</nowiki>** ont recherché les fichiers **423** et **=424**, sans les trouver. | ||
+ | |||
+ | Les opérateur de comparaison sont des opérateurs binaires, ils attendent donc 2 arguments (ou opérandes).\\ | ||
+ | Les commande **<nowiki>((</nowiki>** et **let** retournent une erreur s'il manque un opérande. | ||
+ | <code> | ||
+ | (( == 0)) ; echo $? | ||
+ | let 0>= ; echo $? | ||
+ | echo ===== | ||
+ | (( 42 < "")) ; echo $? | ||
+ | let ""!=24 ; echo $? | ||
+ | </code> | ||
+ | <file config retour des commandes> | ||
+ | bash: ((: == 0 : erreur de syntaxe : opérande attendu (le symbole erroné est « == 0 ») | ||
+ | 1 | ||
+ | bash: let: une expression est attendue | ||
+ | 1 | ||
+ | ===== | ||
+ | bash: ((: 42 < : erreur de syntaxe : opérande attendu (le symbole erroné est « < ») | ||
+ | 1 | ||
+ | bash: let: !=24 : erreur de syntaxe : opérande attendu (le symbole erroné est « !=24 ») | ||
+ | 1 | ||
+ | </file> | ||
+ | |||
+ | Les opérandes ne peuvent être des chaînes de caractères contenant des espaces. | ||
+ | |||
+ | __Rappel :__ L'option **-e** de la commande **echo** permet de développer les caractères protégés, (ici **\n** qui se développe en saut de ligne).\\ | ||
+ | Le développement des caractères protégés se réalisent entre guillemets doubles.\\ | ||
+ | Sans guillemets, il est nécessaire de protégé le caractère de protection (**\\n**). | ||
+ | |||
+ | <code> | ||
+ | echo ===== | ||
+ | (("Du texte" >= 0)) | ||
+ | echo -e '(("Du texte" >= 0)) revoie le code de retour' $?\\n | ||
+ | let 424\>"Du texte" | ||
+ | echo -e 'let 424\>"Du texte" revoie le code de retour' $?\\n | ||
+ | echo ===== | ||
+ | n="Du texte" | ||
+ | ((0<=n)) | ||
+ | echo -e "Avec n=\"$n\" ; ((0<=n)) renvoie le code retour $?\n" | ||
+ | let n==0 | ||
+ | echo "Avec n=\"${n}\" ; let n==0 renvoie le code retour $?" | ||
+ | </code> | ||
+ | <file config retour des commandes>===== | ||
bash: ((: Du texte >= 0 : erreur de syntaxe dans l'expression (le symbole erroné est « texte >= 0 ») | bash: ((: Du texte >= 0 : erreur de syntaxe dans l'expression (le symbole erroné est « texte >= 0 ») | ||
- | (("Du texte" >= 0)) revoie le code de retour 1 | + | (("Du texte" >= 0)) revoie le code de retour 1 |
- | (("DuTexte" == 0)) revoie le code de retour 0 | + | bash: let: 424>Du texte : erreur de syntaxe dans l'expression (le symbole erroné est « texte ») |
+ | let 424\>"Du texte" revoie le code de retour 1 | ||
+ | ===== | ||
bash: ((: Du texte : erreur de syntaxe dans l'expression (le symbole erroné est « texte ») | bash: ((: Du texte : erreur de syntaxe dans l'expression (le symbole erroné est « texte ») | ||
- | Avec n="Du texte" ; ((n>=0)) renvoie le code retour 1 | + | Avec n="Du texte" ; ((0<=n)) renvoie le code retour 1 |
- | Avec n="DuTexte" ; ((n!=0)) renvoie le code retour 1 | + | bash: let: Du texte : erreur de syntaxe dans l'expression (le symbole erroné est « texte ») |
+ | -Avec n="Du texte" ; let n==0 renvoie le code retour 1 | ||
</file> | </file> | ||
+ | |||
+ | <note> | ||
+ | Remarquons que les commandes **let** et **<nowiki>((</nowiki>** renvoie le code de retour 1 quand elles sont en erreur. Ce n'est pas la norme pour une commande interne de bash. Le code de retour devrait être 2. | ||
+ | </note> | ||
==== Exemple dans un script ==== | ==== Exemple dans un script ==== |