diff --git a/unix/shell/boucle.tml b/unix/shell/boucle.tml new file mode 100644 index 0000000..07af43a --- /dev/null +++ b/unix/shell/boucle.tml @@ -0,0 +1,633 @@ + + + +
++Une fois que vous avez compris qu'un script n'est rien d'autre qu'une +suite de commandes, vous avez fait un grand pas ; chaque script +consiste à poser des rails, il ne reste plus à l'utilisateur qu'à les +parcourir. +
+ +Toutefois, avoir posé les rails ne suffit pas toujours : il peut +importer de disposer de mécanismes d'aiguillage. Les boucles vous +permettront de réaliser ces mécanismes d'aiguillage, qui donneront à vos +scripts souplesse et efficacité.
+ + + +if
et case
if
+Robert le jardinier programme un hachoir en shell, et veut en interdire
+l'accès à tout autre utilisateur que lui-même, afin de protéger le petit
+Émile de ce dangereux instrument. Le programme hachoir
se
+pose la question suivante : est-ce que $USER
vaut
+« Robert » ?
+
+C'est pour les structures de type « si... alors... ou sinon »,
+la commande if
a été faite. Elle est constituée de cinq
+termes, dont trois sont obligatoires :
if
(si), qui marque la condition à remplir ;
+then
(alors), qui marque les conséquences si la
+condition est remplie ; elif
(contraction de else if, qui signifie
+« sinon, si... »), qui est facultatif et marque une
+condition alternative ;else
(sinon), qui est facultatif et marque le
+comportement à adopter si la condition n'est pas remplie ; fi
(if
à l'envers), qui marque la fin de
+la boucle.On peut donc taper :
+ +if commande ; then commandes ; else commandes ; fi+ +
ou bien (car le point et virgule équivaut à un saut +de ligne) :
+ +if condition + then commandes +elif condition + then commandes +else commandes +fi+ + +
+Par exemple, pour le hachoir de Robert le jardinier, on aura : +
+ ++if test $USER = Robert + then echo "Le hachoir va se mettre en marche." + mettre en marche le hachoir +else echo "Quand tu seras grand, $USER." + echo "Et fais bien attention en traversant la rue." +fi+ + +
Comme vous pouvez le constater, à la suite des commandes
+then
et else
, vous pouvez mettre autant de
+commandes que vous le voulez. Le shell exécute tout ce qu'il
+trouve jusqu'à la prochaine instruction.
Par exemple, si la condition indiquée par if
est
+remplie, le shell va exécuter tout ce qui suit then
jusqu'à
+ce qu'il trouve l'une de ces instructions :
elif
,else
oufi
.Autre exemple :
+ ++#!/bin/sh +# Fichier "mon-pwd" + +if test $PWD = $HOME + then echo "Vous êtes dans votre répertoire d'accueil." +elif test $PWD = $HOME/bin + then echo "Vous êtes dans votre répertoire d'exécutables." +elif test $PWD = $HOME/bin/solaris + then echo "Vous êtes dans votre répertoire d'exécutables pour Solaris." +else echo 'Vous êtes dans un répertoire quelconque, qui n'est ni $HOME,' + echo 'ni $HOME/bin, ni $HOME/bin/solaris. '"Vous êtes dans $PWD." +fi ++ +
elif
successifs est
+illimité, alors qu'il ne peut (et c'est logique) y avoir qu'une
+seule condition if
, une seule instruction else
+et une seule instruction fi
dans une boucle. $HOME
+est cité dans des guillemets simples, alors que $PWD
est
+cité entre guillemets doubles. Par conséquent, $HOME ne sera pas
+interprété (le mot « $HOME » apparaîtra tel quel), tandis que
+$PWD
sera interprété (il sera remplacé, par exemple, par
+/home/toto
).case
case
à if
?La boucle if
est très pratique, mais devient rapidement
+illisible lorsqu'un aiguillage offre plusieurs sorties, et que l'on doit
+répéter une condition pusieurs fois sous des formes à peine
+différentes. Typiquement, un programme comme celui-ci est pénible à
+écrire, à lire et à débuguer :
+if test $PWD = $HOME + then echo "Vous êtes dans votre répertoire d'accueil." +elif test $PWD = $HOME/bin + then echo "Vous êtes dans votre répertoire d'exécutables." +elif test $PWD = $HOME/bin/solaris + then echo "Vous êtes dans votre répertoire d'exécutables pour Solaris." +elif test $PWD = $HOME/prive + then echo "Vous êtes dans votre répertoire privé." +else echo 'Vous êtes dans un répertoire quelconque, qui n'est ni $HOME,' + echo 'ni $HOME/bin, ni $HOME/bin/solaris. '"Vous êtes dans $PWD." +fi ++ +
Pourquoi ce programme est-il pénible à écrire, à lire et à +débuguer ?
+ +test
+$PWD =
» ; et qui dit redondance dit possibilité de
+faute de frappe – erreur particulièrement difficile à repérer
+à l'œil nu ;if
n'est pas, dans la boucle, sur le même plan que
+elif
, alors que logiquement les deux instructions le
+sont), ce qui nuit à la lisibilité.La boucle case
entend remédier à ces inconvénients. Il
+s'agit tout simplement de la simplification d'un usage fréquent de la
+structure if
. On peut récrire le programme suivant avec
+case
:
+case "$PWD" in +"$HOME") echo "Vous êtes dans votre répertoire d'accueil.";; +"$HOME/bin") echo "Vous êtes dans votre répertoire d'exécutables.";; +"$HOME/bin/solaris") echo "Vous êtes dans votre répertoire d'exécutables pour Solaris.";; +"$HOME/prive") echo "Vous êtes dans votre répertoire privé.";; +"*") echo 'Vous êtes dans un répertoire quelconque, qui n'est ni $HOME,' + echo 'ni $HOME/bin, ni $HOME/bin/solaris. '"Vous êtes dans $PWD.";; +esac ++ +
Le gain de lisibilité est flagrant (si si, c'est flagrant, je vous +assure) :
+ +elif
;case
La boucle case
adopte la syntaxe suivante :
+case chaîne in + motif) commandes ;; + motif) commandes ;; +esac ++ +
+La boucle case
commence par évaluer la
+chaîne. Ensuite, elle va lire chaque motif. Enfin, et
+dès qu'une chaîne correspond au motif, elle exécute
+les commandes appropriées. En anglais, case signifie
+« cas » ; cette structure de contrôle permet en effet de
+réagir adéquatement aux différents « cas de figure »
+possibles.
+Vous observerez que : +
+ +case
est close par l'instruction
+esac
, qui n'est autre que le mot case
à
+l'envers (de même que la boucle if
est terminée par
+l'instruction fi
).
+Un motif (pattern) est un mot contenant éventuellement
+les constructions *
, ?
, [a-d]
,
+avec la même signification que pour les raccourcis dans les noms de
+fichiers (les jokers). Exemple :
+
+case $var in + [0-9]*) echo "$var est un nombre.";; + [a-zA-Z]*) echo "$var est un mot.";; + *) echo "$var n'est ni un nombre ni un mot.";; +esac+ + +
Que faire si je veux aiguiller plusieurs motifs différents de la même +façon ? Le premier réflexe est de répéter, presque à l'identique, +des lignes, de la façon suivante :
+ ++#!/bin/sh +# Fichier "canards" + +echo "Quel est ton nom ?" +read nom + +case $nom in +"Riri") echo "Ton oncle s'appelle Donald, Riri.";; +"Fifi") echo "Ton oncle s'appelle Donald, Fifi.";; +"Loulou") echo "Ton oncle s'appelle Donald, Loulou.";; +"*") echo "Tu n'es pas un neveu de Donald.";; +esac ++ +
+Mais il n'est jamais bon de répéter manuellement des lignes de +programmation, car c'est générateur de fautes. Il faut toujours +chercher des raccourcis, et ne se répéter qu'en dernier recours. On +utilisera donc le caractère « | », qui permet de mettre sur le +même plan différents motifs. On pourra donc écrire : +
+ ++#!/bin/sh +# Fichier "canards" + +echo "Quel est ton nom ?" +read nom + +case $nom in +"Riri"|"Fifi"|"Loulou") echo "Ton oncle s'appelle Donald, $nom.";; +"*") echo "Tu n'es pas un neveu de Donald.";; +esac ++ +
On gagne ainsi en concision, et on évite bien des +fautes d'inattention, qui sont particulièrement coriaces à débuguer. +
+ +La boucle case
exécute les commandes correspondant au
+premier motif correct, et ne parcourt pas les motifs
+suivants si elle en a trouvé un. Par conséquent, si le dernier
+motif est « * », cela revient à l'instruction
+else
dans la boucle if
.
while
, until
+et for
Les structures if
et case
sont des
+structures d'aiguillage ; les structures while
,
+until
et for
sont proprement des
+boucles. C'est-à-dire qu'elles soumettent à une condition déterminée la
+répétition (ou non) d'une suite de commandes.
while
+La boucle while
exécute les commandes de manière
+répétée tant que la première commande réussit ; en
+anglais, while signifie « tant que ».
while
La boucle while
adopte la syntaxe suivante :
while condition + do commandes +done+ +
Après l'instruction do
, vous pouvez mettre
+autant de commandes que vous le désirez, suivies de retours
+chariot ou bien de points et virgules (« ; »). Le shell
+exécutera tout ce qu'il trouve, jusqu'à ce qu'il tombe sur l'instruction
+done
.
+echo "Tapez le mot de passe :" +read password + +while test "$password" != mot de passe correct +do echo "Mot de passe incorrect." + echo "Tapez le mot de passe" + read password +done + +echo "Mot de passe correct." +echo "Bienvenue sur les ordinateurs secrets du Pentagone." ++ +
Les lignes qui suivent la boucle while
+seront exécutées si, et seulement si, la condition est remplie,
+c'est-à-dire si l'utilisateur tape le bon mot de passe. (En pratique, il
+est très fortement déconseillé de taper un mot de passe en clair dans un
+script, car rien n'est plus facile que de l'éditer !...).
+
while
Supposons que vous vouliez créer cinquante fichiers sous la forme
+fichier1
, fichier2
, fichier3
,
+etc. Un petit script vous fera ça plus vite que cinquante lignes de
+commande.
+#!/bin/sh +# Fichier "50fichiers" + +numero=1 + +while test $numero != 51 + do + # la commande "touch" permet de créer un fichier vide : + touch fichier"$numero" + + # cette commande ajoute 1 à la variable "numero" : + numero=$(($numero + 1)) +done ++ +
Avec ce script, la variable numero
est
+d'abord créée avec la valeur 1. Ensuite, le shell examine si la
+valeur de numero
est différente de 51 ; c'est le
+cas. Par conséquent, le shell exécute les commandes suivantes : il
+crée un fichier fichier1
, puis ajoute 1 à la variable
+numero
, qui vaut donc 2. Et c'est reparti pour un
+tour ! Le shell examine si la valeur de numero
,
+c'est-à-dire 2, est différente de 51, etc.
+
Petit conseil pour faire les choses le plus proprement +possible : dans le script qui précède, +remplacez « 51 » par une variable : le script sera +beaucoup plus lisible. Exemple :
+ ++#!/bin/sh +# Fichier "50fichiers" + +numero=1 +limite=51 + +while test $numero != $limite + do + # la commande "touch" permet de créer un fichier vide : + touch fichier"$numero" + + # cette commande ajoute 1 à la variable "numero" : + numero=$(($numero + 1)) +done ++ + + +
until
+Until signifie « jusqu'à ce que » en anglais. Cette
+boucle est le pendant de la boucle while
, à ceci près que
+la condition ne détermine pas la cause de la répétition
+de la boucle, mais celle de son interruption.
until
+until condition + do commandes +done ++ +
On aura ainsi :
+ ++echo "Tapez le mot de passe :" +read password + +until test $password = mot de passe correct +do echo "Mot de passe incorrect." + echo "Tapez le mot de passe" + read password +done + +echo "Mot de passe correct." +echo "Bienvenue sur les ordinateurs secrets de la NASA." ++ + +
Il revient en effet au même de répéter une suite de commandes +« tant que le mot de passe est +incorrect » ou bien « jusqu'à ce que +le mot de passe soit correct », car un mot de +passe déterminé ne peut être que correct ou incorrect. +
+ + +while
ou until
?Vous allez donc me demander que préférer entre while
et
+until
, si les deux sont si souvent équivalentes ? Eh
+bien, celle dont la condition sera la plus facile à écrire, à lire et à
+débuguer. Si, comme dans notre exemple, elles sont aussi simples
+l'une que l'autre, choisissez votre préférée ou prenez-en une au hasard.
+
for
+La boucle for
affecte successivement une variable chaque
+chaîne de caractères trouvée dans une liste de chaînes, et
+exécute les commandes une fois pour chaque chaîne.
+
for
for var in liste de chaînes +do commandes +done+ + + +
+#!/bin/sh +# Fichier "liste" + +for element in * + do echo "$element" +done ++ +
+affiche les noms de tous les fichiers du répertoire courant, un par ligne. +
+ +Concrètement, le shell va prendre la liste des chaînes, en
+l'occurrence « * », c'est-à-dire tous les fichiers et
+répertoires du répertoire courant. À chacun de ces éléments, il va
+attribuer la variable element
, puis exécuter les commandes
+spécifiées, en l'occurrence echo
+"$element"
. Ainsi, si dans mon répertoire j'ai les
+fichiers a
, b
et c
, le shell va
+exécuter successivement echo "a"
, echo
+"b"
et echo "c"
.
for
+Comme while
et until
, for
est une
+boucle au sens propre. Mais il y a une différence notable entre ces deux
+groupes de boucle : while
et until
sont
+plus appropriés à la répétition à l'identique d'une séquence de
+commandes, tandis que for
convient particulièrement
+aux répétitions soumises à de légères variations.
+
+Prenons par exemple le script qui permettait, avec while
,
+de créer 50 fichiers rapidement. La numération des passages par la
+boucle était assez pénible, et éclatée en trois endroits :
+
numero
(et, éventuellement, de la valeur 51 à
+la variable limite
) ;test $numero != 51
ou
+test $numero != $limite
;numero
, avec la
+ligne numero=$(($numero + 1))
.
+Pourquoi dire en trois fois ce qui, dans les langages naturels
+(c'est-à-dire humains), s'énonce en une seule : « répéter
+n fois cette séquence de commandes » ? La boucle
+for
se révèle alors indispensable :
+
+#!/bin/sh +# Fichier "50fichiers-for" + +# la commande "seq a b" compte de a à b +for numero in `seq 1 50` + do touch fichier"$numero" +done ++ +
Avouez que le script est beaucoup plus simple de +cette manière !
+ + +
+On remarque que la condition des commandes if
et
+while
est une commande. Chaque commande renvoie un code de
+retour (qui est ignoré en utilisation normale). Si le code est 0, la
+commande a réussi ; sinon, la commande a échoué. Par exemple, le
+compilateur cc
renvoie un code d'erreur non nul si le
+fichier compilé contient des erreurs, ou s'il n'existe pas.
+
+Les commandes if
et while
considèrent donc le
+code de retour 0 comme « vrai », et tout autre code comme
+« faux ».
+
+Il existe une commande test
, qui évalue des expressions
+booléennes (c'est-à-dire dont la valeur ne peut être que vraie ou
+fausse, 1 ou 0) passées en argument, et renvoie un code de retour en
+fonction du résultat. Elle est bien utile pour les scripts.
+Exemple :
+
+if test $var = foo +then echo 'La variable vaut foo' +else echo 'La variable ne vaut pas foo' +fi+ + + + + + + + diff --git a/unix/shell/index.tml b/unix/shell/index.tml index 2bc6905..f86a44c 100644 --- a/unix/shell/index.tml +++ b/unix/shell/index.tml @@ -66,9 +66,8 @@ Quand le shell est inactif, il affiche une invite (prompt en anglais), qui ressemble à cela : -
-chaland ~ $
-
+chaland ~ $
+
Un curseur, parfois clignotant, indique que le shell attend que vous lui
@@ -212,7 +211,7 @@ l'inverse.
Basé sur un polycopié de Roberto Di Cosmo, Xavier Leroy et Damien
Doligez.
Modifications : Nicolas George, Baptiste Mélès.
-Dernière modification le
echo
+Maintenant que vous savez comment on peut exécuter un script, il s'agit +de le remplir... Commençons par ce qu'il y a de plus simple : +afficher du texte. +
+ +
-C'est avec les structures de contrôle qu'un programme peut commencer à
-devenir sérieux. Le principe général de ces structures est le
-suivant : adapter le comportement du programme selon les réponses
-apportées à certaines questions.
+Traditionnellement, on commence par faire un programme qui affiche
+simplement la ligne « Hello world » (ce qui signifie en
+anglais : bonjour au monde entier). Faites donc un fichier
+helloworld
contenant les lignes suivantes :
+
+#!/bin/sh + +# Fichier "helloworld" +echo "Hello world" ++ +
+Exécutez ensuite ce programme, par exemple en tapant, dans le répertoire +où il se trouve : +
+ +clipper ~ $ ./helloworld
+Hello world
+
++Ça y est, vous avez créé votre premier programme ! Lancez-le autant +de vous que vous voulez, vous avez bien mérité d'être fier de vous.
-Nous avons déjà vu une application possible des structures de contrôle
-en parlant des variables. Le programme hachoir
conçu par
-Robert le jardinier pose la question suivante : est-ce que
-$USER
vaut « Robert » ?
+Exercice : francisez ce script.
if
echo
-La structure de contrôle if
est la plus courante de toutes,
-et la plus élémentaire. Elle est constituée de quatre termes :
if
(si), qui marque la condition à remplir ;
-then
(alors), qui marque les conséquences si la
-condition est remplie ; else
(sinon), qui est facultatif et marque le
-comportement à adopter si la condition n'est pas remplie ; fi
(if
à l'envers), qui marque la fin de
-la boucle.if commande ; then commandes ; else commandes ; fi- -
ou bien (car le point et virgule équivaut à un saut -de ligne) :
- -if commande -then commandes -else commandes -fi- -
-Par exemple, pour Robert le jardinier, on aura :
+La commande echo
sert à afficher du texte sur la sortie
+standard (pour savoir ce qu'est la sortie standard, consultez la page
+sur les entrées et sorties). Chaque
+ligne de texte est écrite sur une ligne à part. Exemple :
if test $USER = Robert - then hacher_menu_comme_chair_à_pâté $* - else echo "Quand tu seras grand, $USER." - echo "Et fais bien attention en traversant la rue." -fi+
+#!/bin/sh +# Fichier "bonjour" + +echo "Bonjour... " +echo "Comment allez-vous ?" ++ +
affiche les lignes suivantes :
+ ++Bonjour... +Comment allez-vous ? ++ +
et non :
+ ++Bonjour... Comment allez-vous ? +- -
for
-La boucle for
affecte successivement une variable chaque
-chaîne de caractères trouvée dans une liste de chaînes, et
-exécute les commandes une fois pour chaque chaîne.
+Si vous voulez annuler le retour chariot qui a lieu par défaut à la fin
+de toute commande echo
, il faut utiliser l'option
+-n
. Le programme sera alors :
for var in liste de chaînes ; do commandes ; done+
+#!/bin/sh -ou bien :
- -for var in liste de chaînes -do commandes -done- - --Rappel :
- -$var
accède à la valeur courante de -var. La partie commandes est une suite de commandes, -séparées par des points et virgules (;
) ou des retours à la -ligne. --Exemple : -
- -for i in *; do echo "$i"; done+echo -n "Bonjour..." +echo "Comment allez-vous ?" +
-affiche les noms de tous les fichiers du répertoire courant, un par ligne. -
- -
-Remarque : plus un programme grossit, plus il importe que son
-contenu soit lisible. Les noms de variable doivent donc être le
-plus lisibles possible, pour permettre à d'autres gens, ou bien
-à vous-même dans quelques mois, de comprendre rapidement votre script.
-Ainsi, il peut être plus explicite d'écrire, au lieu de « for
-i in *; do echo "$i"; done
» :
-
for fichier in *; do echo "$fichier"; done- -
-En outre, pour des raisons de lisibilité, n'hésitez pas à -gaspiller des lignes de code en sautant des lignes ; les -lignes de code ne sont pas une ressource rare : -
- -for fichier in * -do echo "$fichier" -done- - - -
while
while commande -do commande -done- -
-La boucle while
exécute les commandes de manière
-répétée tant que la première commande réussit.
Par exemple : tant que le mot de passe correct n'a pas -été donné, refuser l'accès et redemander le mot de passe. -
- - - - -case
case chaîne in - pattern) commande ;; - pattern) commande ;; -esac- -
-La boucle case
exécute la première commande telle
-que la chaîne est de la forme pattern. Un
-pattern (motif) est un mot contenant éventuellement les
-constructions *
, ?
, [a-d]
, avec
-la même signification que pour les raccourcis dans les noms de
-fichiers. Exemple :
+Alors seulement, vous pourrez avoir :
-case $var in - [0-9]*) echo 'Nombre';; - [a-zA-Z]*) echo 'Mot';; - *) echo 'Autre chose';; -esac+Bonjour... Comment allez-vous ? + + + +
Faisons mieux encore : votre script va citer des variables. Pour +savoir ce que sont des variables, allez voir la page sur les variables.
+ +La variable USER
contient le login de
+l'utilisateur ; la variable PWD
(pour print
+working directory) affiche le répertoire courant. Faisons donc le
+script suivant :
+#/bin/sh +# Fichier "mon-pwd" + +echo "Bonjour $USER..." +echo "Tu es actuellement dans le répertoire $PWD." ++ +
Comme vous pouvez le remarquer, pour citer le contenu d'une variable, +on ajoute le signe dollar ($) devant son nom.
+ + + + +read
Parler c'est bien, écouter c'est mieux. Jusqu'ici, votre programme +est capable de parler, de dire bonjour, mais il n'est même pas capable +de vous appeler par votre nom, tout juste par votre login, ce qui n'est +pas très intime...
-Vous observerez que l'on clôt la boucle case
avec
-esac
, qui est le mot case
à l'envers, de même
-que l'on clôt if
avec fi
.
-
-On remarque que la condition des commandes if
et
-while
est une commande. Chaque commande renvoie un code de
-retour (qui est ignoré en utilisation normale). Si le code est 0, la
-commande a réussi ; sinon, la commande a échoué. Par exemple, le
-compilateur cc
renvoie un code d'erreur non nul si le
-fichier compilé contient des erreurs, ou s'il n'existe pas.
-
-Les commandes if
et while
considèrent donc le
-code de retour 0 comme « vrai », et tout autre code comme
-« faux ».
-
-Il existe une commande test
, qui évalue des expressions
-booléennes (c'est-à-dire dont la valeur ne peut être que vraie ou
-fausse, 1 ou 0) passées en argument, et renvoie un code de retour en
-fonction du résultat. Elle est bien utile pour les scripts.
-Exemple :
+Nous allons donc lui donner la faculté d'écouter, grâce à la commande
+read
. Prenons le script suivant :
-if test $var = foo -then echo 'La variable vaut foo' -else echo 'La variable ne vaut pas foo' -fi+#!/bin/sh +# Fichier "mon-nom" + +echo "Bonjour... Comment vous-appelez-vous ?" +read nom +echo "Je vous souhaite, $nom, de passer une bonne journée." + + +
Vous connaissez déjà la commande echo
. La commande
+read
permet de lire des variables. Si vous exécutez ce
+script, après avoir affiché la ligne
+Bonjour... Comment vous-appelez-vous ? ++ +
le shell va attendre que vous tapiez votre
+nom. Tapez par exemple Toto
, puis appuyez sur Entrée, et
+vous verrez :
+Bonjour... Comment vous-appelez-vous ? +Toto +Je vous souhaite, Toto, de passer une bonne journée.+ +
read
doit être suivie du seul nom de la
+variable, non précédé du signe dollar. Le signe
+dollar ne doit précéder le nom de la variable que lorsque l'on cite son
+contenu.
+
+La commande read
permet également de lire plusieurs
+variables. Il suffit pour cela d'indiquer à la suite les noms des
+différentes variables. Exemple :
+
+#!/bin/sh +# Fichier "administration" + +echo "Écrivez votre nom puis votre prénom :" +read nom prenom +echo "Nom : $nom" +echo "Prénom : $prenom" ++ +
Vous aurez :
+ ++Écrivez votre nom puis votre prénom : +Hugo Victor +Nom : Hugo +Prénom : Victor +-
Vous êtes maintenant en mesure de faire ces exercices pour vous -entraîner.
+ +Nous avons vu comment utiliser read
avec un seul
+argument et avec plusieurs arguments ; il reste à voir l'usage de
+read
sans argument. Oui, c'est possible !
+Cela équivaut simplement à attendre un réaction de l'utilisateur, mais
+sans mémoriser ce qu'il tape.
Concrètement, cela est très utile après un message « Appuyez +sur Entrée pour continuer. » Exemple :
+ ++#!/bin/sh +# Fichier "continuer" + +echo "Quelle est la différence entre un canard ?" +echo "(Appuyez sur Entrée pour avoir la réponse)" +read +echo "Les pattes, surtout la gauche." +