Aller au menu - Aller au contenu

Icône Les conditions

Mise à jour : 20/11/2011
Difficulté : Difficile Difficile Creative Commons BY-NC-SA
73 501 visites depuis 7 jours , dont 1 024 sur ce chapitre , classé 6/777
La prise de décision est un élément indispensable dans tout programme. Si on ne pouvait pas décider quoi faire, le programme ferait toujours la même chose... ce qui serait bien ennuyeux. :-°

Les branchements conditionnels (que nous abrègerons "conditions") sont un moyen de dire dans notre script "SI cette variable vaut tant, alors fais ceci, sinon fais cela".
Si vous avez déjà vu un autre langage de programmation, cela doit vous être familier. Sinon, ne vous en faites pas, vous allez très vite comprendre le concept. :)
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

if : la condition la plus simple

Le type de condition le plus courant est le if, qui signifie "si".

Si



Les conditions ont la forme suivante :

Citation
SI test_de_variable
ALORS
------> effectuer_une_action
FIN SI


Bien entendu, ce n'est pas du bash ça. C'est juste un schéma pour vous montrer quelle est la forme d'une condition.

La syntaxe en bash est la suivante :

Code : Bash
1
2
3
4
if [ test ]
then
	echo "C'est vrai"
fi


Le mot "fi" (if à l'envers !) à la fin indique que le if s'arrête là. Tout ce qui est entre le then et le fi sera exécuté uniquement si le test est vérifié.

Vous noterez, c'est très important, qu'il y a des espaces à l'intérieur des crochets. On ne doit pas écrire [test] mais [ test ] !


Il y a une autre façon d'écrire le if : en plaçant le then sur la même ligne. Dans ce cas, il ne faut pas oublier de rajouter un point-virgule après les crochets :

Code : Bash
1
2
3
if [ test ]; then
	echo "C'est vrai"
fi


A la place du mot "test", il faut indiquer votre test. C'est à cet endroit que vous testerez la valeur d'une variable par exemple. Nous allons voir ici un cas simple où nous testons la valeur d'une chaîne de caractères, puis nous apprendrons à faire des tests plus compliqués un peu plus loin.

Faisons quelques tests sur un script que nous appellerons "conditions.sh" :

Code : Bash
1
2
3
4
5
6
7
8
#!/bin/bash

nom="Bruno"

if [ $nom = "Bruno" ]
then
        echo "Salut Bruno !"
fi


Comme $nom est bien égal à "Bruno", ce script affichera :

Code : Console
Salut Bruno !


Essayez de changer le test, si vous n'écrivez pas précisément "Bruno", le if ne sera pas exécuté, et donc votre script n'affichera rien.

Notez aussi que vous pouvez tester 2 variables à la fois dans le if :

Code : Bash
1
2
3
4
5
6
7
8
9
#!/bin/bash

nom1="Bruno"
nom2="Marcel"

if [ $nom1 = $nom2 ]
then
        echo "Salut les jumeaux !"
fi


Comme ici $nom1 est différent de $nom2, le contenu du if ne sera pas exécuté. Le script n'affichera donc rien.


Sinon



Si vous souhaitez faire quelque chose de particulier quand la condition n'est pas remplie, vous pouvez rajouter un "else" qui signifie "sinon".

En français, ça s'écrirait comme ceci :

Citation
SI test_de_variable
ALORS
------> effectuer_une_action
SINON
------> effectuer_une_action
FIN SI


Code : Bash
1
2
3
4
5
6
if [ test ]
then
	echo "C'est vrai"
else
	echo "C'est faux"
fi


Reprenons notre script de tout à l'heure, et ajoutons-lui un else :

Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/bash

nom="Bruno"

if [ $nom = "Bruno" ]
then
        echo "Salut Bruno !"
else
        echo "J'te connais pas, ouste !"
fi


Bon, comme la variable vaut toujours la même chose, le else ne sera jamais exécuté, ce n'est pas rigolo. Je vous propose plutôt de vous baser sur le premier paramètre ($1) envoyé au script :

Code : Bash
1
2
3
4
5
6
7
8
#!/bin/bash

if [ $1 = "Bruno" ]
then
        echo "Salut Bruno !"
else
        echo "J'te connais pas, ouste !"
fi


Testez maintenant votre script en lui donnant un paramètre :

Code : Console
$ ./conditions.sh Bruno
Salut Bruno !


Et si vous mettez autre chose :

Code : Console
$ ./conditions.sh Jean
J'te connais pas, ouste !


Notez que le script plante si vous oubliez de l'appeler avec un paramètre. Pour bien faire, il faudrait d'abord vérifier dans un if s'il y a au moins un paramètre. Nous apprendrons à faire cela plus loin.


Sinon si



Il existe aussi le mot-clé "elif", abréviation de "else if", qui signifie "sinon si". Sa forme ressemble à cela :

Citation
SI test_de_variable
ALORS
------> effectuer_une_action
SINON SI autre_test
ALORS
------> effectuer_une_action
SINON SI encore_un_autre_test
ALORS
------> effectuer_une_action
SINON
------> effectuer_une_action
FIN SI


C'est un peu plus compliqué hein ? ;)

Sachez qu'on peut mettre autant de "sinon si" qu'on veut. Là j'en ai mis deux. En revanche, on ne peut mettre qu'un seul "sinon", qui sera exécuté à la fin si aucune des conditions précédentes n'est vérifiée.

Bash va d'abord analyser le premier test. S'il est vérifié, il effectuera la première action indiquée, sinon il ira au premier sinon si, au second, etc., jusqu'à trouver une condition qui soit vérifiée. Si aucune condition n'est vérifiée, c'est le "sinon" qui sera lu.

Bien, voyons comment cela s'écrit en bash :

Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
if [ test ]
then
	echo "Le premier test a été vérifié"
elif [ autre_test ]
then
	echo "Le second test a été vérifié"
elif [ encore_autre_test ]
then
	echo "Le troisième test a été vérifié"
else
	echo "Aucun des tests précédents n'a été vérifié"
fi


On peut reprendre notre script précédent et l'adapter pour utiliser des elif :

Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash

if [ $1 = "Bruno" ]
then
	echo "Salut Bruno !"
elif [ $1 = "Michel" ]
then
	echo "Bien le bonjour Michel"
elif [ $1 = "Jean" ]
then
	echo "Hé Jean, ça va ?"
else
	echo "J'te connais pas, ouste !"
fi


Vous pouvez tester ce script, encore une fois n'oubliez pas d'envoyer un paramètre sinon il plantera, ce qui est normal.

Les tests

Voyons maintenant un peu quels tests on peut faire. Pour l'instant on a juste testé si 2 chaînes de caractères étaient identiques, mais on peut faire beaucoup plus de choses que ça !

Les différents types de tests



On peut faire 3 types de tests différents en bash :

  • Tests sur des chaînes de caractères
  • Tests sur des nombres
  • Tests sur des fichiers


Nous allons découvrir tous ces types de tests maintenant et les essayer. :)

Tests sur des chaînes de caractères



Comme vous le savez maintenant, en bash toutes les variables sont considérées comme des chaînes de caractères. Il est donc très facile de tester ce que vaut une chaîne de caractères.

ConditionSignification
$chaine1 = $chaine2 Teste si les 2 chaînes sont identiques. Notez que bash est sensible à la casse : "b" est donc différent de "B".
Il est aussi possible d'écrire 2 "==" pour les habitués du langage C.
$chaine1 != $chaine2 Teste si les 2 chaînes sont différentes
-z $chaine Teste si la chaîne est vide
-n $chaine Teste si la chaîne est non vide


Testons par exemple si 2 paramètres sont différents :

Code : Bash
1
2
3
4
5
6
7
8
#!/bin/bash

if [ $1 != $2 ]
then
	echo "Les 2 paramètres sont différents !"
else
	echo "Les 2 paramètres sont identiques !"
fi


Code : Console
$ ./conditions.sh Bruno Bernard
Les 2 paramètres sont différents !


Code : Console
$ ./conditions.sh Bruno Bruno
Les 2 paramètres sont identiques !


On peut aussi tester si le paramètre existe avec -z (teste si la chaîne est vide). En effet, si une variable n'est pas définie, elle est considérée comme vide par bash. On peut donc par exemple s'assurer que $1 existe comme ceci :

Code : Bash
1
2
3
4
5
6
7
8
#!/bin/bash

if [ -z $1 ]
then
	echo "Pas de paramètre"
else
	echo "Paramètre présent"
fi


Code : Console
$ ./conditions.sh 
Pas de paramètre


Code : Console
$ ./conditions.sh param
Paramètre présent



Tests sur des nombres



Bien que bash gère les variables comme des chaînes de caractères pour son fonctionnement interne, rien ne nous empêche de faire des comparaisons de nombres si ces variables contiennent des nombres.

ConditionSignification
$num1 -eq $num2 Teste si les nombres sont égaux (equal). A ne pas confondre avec le "=" qui, lui, compare 2 chaînes de caractères.
$num1 -ne $num2 Test si les nombres sont différents (non equal). Encore une fois, ne confondez pas avec "!=" qui est censé être utilisé sur des chaînes de caractères.
$num1 -lt $num2 Teste si num1 est inférieur ( < ) à num2 (lower than)
$num1 -le $num2 Teste si num1 est inférieur ou égal ( <= ) à num2 (lower or equal)
$num1 -gt $num2 Teste si num1 est supérieur ( > ) à num2 (greater than)
$num1 -ge $num2 Teste si num1 est supérieur ou égal ( >= ) à num2 (greater or equal)


Testons par exemple si un nombre est supérieur ou égal à un autre nombre :

Code : Bash
1
2
3
4
5
6
7
8
#!/bin/bash

if [ $1 -ge 20 ]
then
	echo "Vous avez envoyé 20 ou plus"
else
	echo "Vous avez envoyé moins de 20"
fi


Code : Console
$ ./conditions.sh 23
Vous avez envoyé 20 ou plus


Code : Console
$ ./conditions.sh 11
Vous avez envoyé moins de 20


Tests sur des fichiers



Un des avantages de bash sur d'autres langages est qu'on peut très facilement faire des tests sur des fichiers : savoir s'ils existent, si on peut écrire dedans, s'ils sont plus vieux, plus récents, etc.

ConditionSignification
-e $nomfichier Teste si le fichier existe
-d $nomfichier Teste si le fichier est un répertoire. N'oubliez pas que sous Linux, tout est considéré comme un fichier, même les répertoires !
-f $nomfichier Teste si le fichier est un... fichier. Un vrai fichier cette fois, pas un dossier. ;)
-L $nomfichier Teste si le fichier est un lien symbolique (raccourci)
-r $nomfichier Teste si le fichier est lisible (r)
-w $nomfichier Teste si le fichier est modifiable (w)
-x $nomfichier Teste si le fichier est exécutable (x)
$fichier1 -nt $fichier2 Teste si fichier1 est plus récent que fichier2 (newer than)
$fichier1 -ot $fichier2 Teste si fichier1 est plus vieux que fichier2 (older than)


Je vous propose de faire un script qui demande à l'utilisateur de rentrer le nom d'un répertoire, et qui vérifie si c'est bien un répertoire :

Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/bash

read -p 'Entrez un répertoire : ' repertoire

if [ -d $repertoire ]
then
	echo "Bien, vous avez compris ce que j'ai dit !"
else
	echo "Vous n'avez rien compris..."
fi


Code : Console
Entrez un répertoire : /home
Bien, vous avez compris ce que j'ai dit !


Code : Console
Entrez un répertoire : rienavoir.txt
Vous n'avez rien compris...


Notez que bash vérifie au préalable que le répertoire existe bel et bien.


Effectuer plusieurs tests à la fois



Dans un if, il est possible de faire plusieurs tests à la fois. En général, on vérifie :

  • Si un test est vrai ET qu'un autre test est vrai
  • Si un test est vrai OU qu'un autre test est vrai


Les 2 symboles à connaître sont :

  • && : signifie "et"
  • || : signifie "ou"


Il faut encadrer chaque condition par des crochets. Prenons un exemple :

Code : Bash
1
2
3
4
5
6
7
8
9
#!/bin/bash

if [ $# -ge 1 ] && [ $1 = 'koala' ]
then
	echo "Bravo !"
	echo "Vous connaissez le mot de passe"
else
	echo "Vous n'avez pas le bon mot de passe"
fi


Le test vérifie 2 choses :

  • Qu'il y a au moins un paramètre ("si $# est supérieur ou égal à 1")
  • Que le premier paramètre est bien koala ("si $1 est égal à koala")


Si ces 2 conditions sont remplies, alors le message indiquant qu'on a trouvé le bon mot de passe s'affichera.

Code : Console
$ ./conditions.sh koala
Bravo !
Vous connaissez le mot de passe


Notez que les tests sont effectués l'un après l'autre, et seulement s'ils sont nécessaires. Bash vérifie d'abord s'il y a au moins un paramètre. Si ce n'est pas le cas, il ne fera pas le second test puisque la condition sera de toute façon fausse.


Inverser un test



Il est possible d'inverser un test en utilisant la négation. En bash, c'est le point d'exclamation "!" qui exprime la négation.

Code : Bash
1
2
3
4
if [ ! -e fichier ]
then
	echo "Le fichier n'existe pas"
fi


Vous en aurez besoin, donc n'oubliez pas ce petit point d'exclamation. :)

case : tester plusieurs conditions à la fois

On a vu tout à l'heure un if un peu complexe, qui faisait appel à des elif et un else :

Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash

if [ $1 = "Bruno" ]
then
	echo "Salut Bruno !"
elif [ $1 = "Michel" ]
then
	echo "Bien le bonjour Michel"
elif [ $1 = "Jean" ]
then
	echo "Hé Jean, ça va ?"
else
	echo "J'te connais pas, ouste !"
fi


Ce genre de "gros if qui teste toujours la même variable" ne pose pas de problème mais n'est pas forcément très facile à lire pour le programmeur. On peut utiliser si on veut à la place l'instruction case.

Le rôle de case est de tester la valeur d'une même variable, mais de manière plus concise et lisible.

Voyons comment on écrirait la condition précédente avec un case :

Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/bin/bash

case $1 in
	"Bruno")
		echo "Salut Bruno !"
		;;
	"Michel")
		echo "Bien le bonjour Michel"
		;;
	"Jean")
		echo "Hé Jean, ça va ?"
		;;
	*)
		echo "J'te connais pas, ouste !"
		;;
esac


Ca fait beaucoup de nouveautés d'un coup. :p
Analysons la structure du case !

Code : Bash
1
case $1 in


Tout d'abord, on indique que l'on veut tester la valeur de la variable $1. Bien entendu, vous pouvez remplacer $1 par n'importe quelle variable que vous voulez tester.

Code : Bash
1
"Bruno")


Là, on teste une valeur. Cela signifie "Si $1 est égal à Bruno". Notez qu'on peut aussi utiliser une étoile comme joker : "B*" acceptera tous les mots qui commencent par un B majuscule.

Si la condition est vérifiée, tout ce qui suit est exécuté jusqu'au prochain double point-virgule :

Code : Bash
1
;;


Important, il ne faut pas l'oublier : le double point-virgule dit à bash d'arrêter la lecture du case là. Il saute donc à la ligne qui suit le "esac" qui signale la fin du case.

Code : Bash
1
*)


C'est en fait le "else" du case. Si aucun des tests précédents n'a été vérifié, alors c'est cette section qui sera lue.

Code : Bash
1
esac


Marque la fin du case (esac, c'est "case" à l'envers !).


On peut aussi faire des "ou" dans un case. Dans ce cas, petit piège, il ne faut pas mettre deux || mais un seul ! Exemple :

Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash

case $1 in
	"Chien" | "Chat" | "Souris")
		echo "C'est un mammifère"
		;;
	"Moineau" | "Pigeon")
		echo "C'est un oiseau"
		;;
	*)
		echo "Je ne sais pas ce que c'est"
		;;
esac

Q.C.M.

Quel mot-clé signifie "sinon si" ?
J'ai voulu mettre le then sur la même ligne que le if. Quelle erreur ai-je faite ?


Code : Bash
1
if [ $var = "test" ] then
Que signifie -lt quand on compare 2 nombres ?
Quel mot-clé détermine la fin d'un case ?
Que va afficher ce code ?


Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/bash

age=13
ville='Avignon'

if [ $age -gt 13 ] || [ $ville = 'Avignon' ]
then
	echo "Vous êtes autorisé à entrer"
else
	echo "Vous n'êtes pas invité !"
fi

Statistiques de réponses au QCM

Vous venez d'avoir un bon tour d'horizon de ce qu'il est possible de tester en bash ! :)

Avec ces nouvelles connaissances, vous pouvez commencer à faire des scripts intéressants, surtout si vous utilisez les paramètres ($1, $2...) que l'utilisateur peut rentrer.

On s'entraînera plus loin à faire des scripts plus complets car, malgré sa syntaxe un peu particulière, on peut connaître l'essentiel du bash rapidement, mais réaliser de "gros scripts" est un peu plus complexe et nécessite un peu d'expérience... d'où la nécessité je pense de faire un petit TP tout à l'heure. ;)

Bien, il nous reste à voir les boucles et nous pourrons commencer à pratiquer pour de bon !
Chapitre précédent Sommaire Chapitre suivant

Partager

9 commentaires pour "Les conditions"
Note moyenne : 3.81 / 4 (995 votes)
Pseudo Commentaire
Hors ligne smilz # Posté le 28/05/2009 à 18:41:25
La vie est une blague
Avatar
Flux RSS

Il faudrait préciser que dans elif, une fois une condition vérifier, toutes les autres sont sautées, il faut donc parfois user de pleins if - fi au lieu d'un gros if - elif - fi, de plus, tu ne dis pas que dans un if - elif, le else est aussi facultatif (pas bien grave) et pour le signes de comparaison, des
≠ = ≥ ≤ seraient plus propres. Quitte à rajouter une colonne « équivalent en C », les signes que je propose sont « plus parlant » pour le néophyte.
Hors ligne deax_one # Posté le 17/06/2009 à 13:26:13

Salut Mateo,

merci poiur tous tes tutos, que je suis depuis quelques temps maintenant.

Concernant ce tuto, il serait bon de préciser d'encadrer les variables à tester par des double quotes.
Sinon, quand tu testes une variable vide (ce qui arrive dans quelques scripts), tu as une erreur.

Du coup,
Code : Bash
1
if [ "$1" = "toto" ]

est mieux que
Code : Bash
1
if [ $1 = "toto" ]
Hors ligne Jarode01 # Posté le 22/07/2009 à 05:02:04

Citation : m@teo
-z $chaine Teste si la chaîne est vide
-n $chaine Teste si la chaîne est non vide


Heu pourquoi a t'on créé les 2 test ci dessus au lieu d'en créer un seul et de mettre un ! devant pour tester le contraire ? :o

Sinon bravo pour ce tuto c'est super mais dommage qu'il n'y en ai pas un autre qui suive celui là et o`u l'on voit des choses plus pointu car j'ai soif de connaissance moi ! :)

Un SUPER Site et Forum sur l'étude et l'élevage des FOURMIS:
Image utilisateur
 
Hors ligne farid63100 # Posté le 24/07/2009 à 00:23:54

Peut-on tester des nombres dans un case? j'ai essayer, je n'y arrive pas.
Hors ligne lufoqre # Posté le 30/11/2009 à 21:06:27

Bonjour, je suis désolé de faire le curieux, mais on peut utiliser | pour faire un ou dans case, on peut aussi utiliser & ?

Voir tous les commentaires