<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://lea-linux.org/docs/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Helix</id>
	<title>Lea Linux - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://lea-linux.org/docs/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Helix"/>
	<link rel="alternate" type="text/html" href="https://lea-linux.org/documentations/Sp%C3%A9cial:Contributions/Helix"/>
	<updated>2026-04-24T21:24:55Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.40.1</generator>
	<entry>
		<id>https://lea-linux.org/docs/index.php?title=Script_shell&amp;diff=16030</id>
		<title>Script shell</title>
		<link rel="alternate" type="text/html" href="https://lea-linux.org/docs/index.php?title=Script_shell&amp;diff=16030"/>
		<updated>2008-09-23T13:45:28Z</updated>

		<summary type="html">&lt;p&gt;Helix : /* Le passage de paramètres */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Développer sous Linux]]&lt;br /&gt;
= Programmation de scripts : Une introduction =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;leatitre&amp;quot;&amp;gt;Programmation de Script: Une introduction&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;leadesc&amp;quot;&amp;gt;Comment écrire de petits scripts permettant d’automatiser la réalisation de taches répétitives.&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Vous aurez envie d’écrire un script (petit programme écrit avec un langage simple : &#039;&#039;shell&#039;&#039;, &#039;&#039;perl&#039;&#039; ou autre) dès que vous aurez tapé dans un terminal quatre fois la même série de commandes et que vous vous apercevrez que vous êtes amené à le refaire de nombreuses fois.&lt;br /&gt;
&lt;br /&gt;
Un script est une suite d’instructions élémentaires qui sont éxécutées de façon séquencielle (les unes après les autres) par le langage de script. Dans cet article nous nous limiterons à l’utilisation du &#039;&#039;shell&#039;&#039; comme langage, et en particulier à du &#039;&#039;shell&#039;&#039; &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt;. En guise de première introduction, vous pouvez lire ce qui concerne les commandes du shell dans l’article [[Admin-admin_env-shell|Le Shell et les Commandes]]. Attention, n’espérez pas que le présent document constitue un manuel complet de programmation ! C’est une courte introduction qui nous l’espérons, vous permettra d’écrire de petits scripts qui vous rendront de précieux services.&lt;br /&gt;
&lt;br /&gt;
== Notions de base ==&lt;br /&gt;
&lt;br /&gt;
=== Mon premier script ===&lt;br /&gt;
&lt;br /&gt;
Pour commencer, il faut savoir qu&#039;un script est un fichier texte standard pouvant être créé par n&#039;importe quel éditeur : [[Software-soft_edit-vi|vi]], [[Software-soft_edit-emacs|emacs]], kedit, gnotepad, ou autre. D&#039;autre part, conventionnellement, un script commence par une ligne de commentaire contenant le nom du langage à utiliser pour interpréter ce script, soit dans notre cas : &amp;lt;code&amp;gt;/bin/sh&amp;lt;/code&amp;gt; (on parle alors de &amp;quot;script shell&amp;quot;). Donc un script shell élémentaire pourrait être :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code multi&amp;gt;#!/bin/sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;cadre type=note&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note :&#039;&#039;&#039; &amp;lt;code&amp;gt;&amp;quot;#!&amp;quot;&amp;lt;/code&amp;gt; se prononce « &#039;&#039;she bang&#039;&#039; », soit « chi-bang ».&lt;br /&gt;
&amp;lt;/cadre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Évidemment un tel script ne fait rien ! Changeons cela. La commande qui affiche quelque chose à l’écran est &amp;lt;code&amp;gt;echo&amp;lt;/code&amp;gt;. Donc pour créer le script &amp;lt;code&amp;gt;bonjour_monde&amp;lt;/code&amp;gt; nous pouvons écrire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
echo &amp;quot;Bonjour, Monde !&amp;quot;&lt;br /&gt;
echo &amp;quot;Un premier script est né.&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comment on l’exécute ? C’est simple il suffit de taper :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[user@becane user]$ sh bonjour_monde&lt;br /&gt;
Bonjour, Monde !&lt;br /&gt;
Un premier script est né.&lt;br /&gt;
[user@becane user]$ _&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
C’est pas cool, vous auriez préféré taper quelque chose comme :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[user@becane user]$ ./bonjour_monde&lt;br /&gt;
Bonjour, Monde !&lt;br /&gt;
Un premier script est né.&lt;br /&gt;
[user@becane user]$ _&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
C’est possible si vous avez au préalable rendu votre script exécutable par la commande :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[user@becane user]$ chmod +x bonjour_monde&lt;br /&gt;
[user@becane user]$ ./bonjour_monde&lt;br /&gt;
Bonjour, Monde !&lt;br /&gt;
Un premier script est né.&lt;br /&gt;
[user@becane user]$ _&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Résumons&amp;lt;/u&amp;gt; : un script &#039;&#039;shell&#039;&#039; commence par : &amp;lt;code&amp;gt;#!/bin/sh&amp;lt;/code&amp;gt;, il contient des commandes du shell et est rendu exécutable par &amp;lt;code&amp;gt;chmod +x&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Quelques conseils concernant les commentaires ===&lt;br /&gt;
&lt;br /&gt;
Dans un shell-script, est considéré comme un commentaire tout ce qui suit le caractère # et ce, jusqu’à la fin de la ligne. Usez et abusez des commentaires : lorsque vous relirez un script 6 mois après l’avoir écrit, vous serez bien content de l’avoir documenté. Un programme n’est jamais trop documenté, en revanche il peut être mal documenté ! Un commentaire est bon lorsqu’il décrit pourquoi on fait quelque chose, pas quand il décrit ce que l’on fait.&lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
# pour i parcourant tous les fichiers,&lt;br /&gt;
for i in ./* ; do&lt;br /&gt;
# copier le fichier vers .bak&lt;br /&gt;
 cp &amp;quot;$i&amp;quot; &amp;quot;$i.bak&amp;quot;&lt;br /&gt;
# fin pour&lt;br /&gt;
done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que fait le script ? Les commentaires ne l’expliquent pas ! Ce sont de mauvais commentaires.&lt;br /&gt;
&lt;br /&gt;
En revanche :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
# on veut faire un copie de tous les fichiers&lt;br /&gt;
for i in ./* ; do&lt;br /&gt;
# sous le nom *.bak&lt;br /&gt;
 cp &amp;quot;$i&amp;quot; &amp;quot;$i.bak&amp;quot;&lt;br /&gt;
done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Là au moins, on sait ce qu’il se passe (il n’est pas encore important de connaître les commandes de ces deux fichiers).&lt;br /&gt;
&lt;br /&gt;
=== Le passage de paramètres ===&lt;br /&gt;
&lt;br /&gt;
Un script ne sera, en général, que d’une utilisation marginale si vous ne pouvez pas modifier son comportement d&#039;une manière ou d&#039;une autre. On obtient cet effet en « passant » un (ou plusieurs) paramètre(s) au script &#039;&#039;via&#039;&#039; la ligne de commande. Voyons comment faire cela. Soit le script &amp;lt;code&amp;gt;essai01&amp;lt;/code&amp;gt; : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
echo le paramètre \$1 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
echo le paramètre \$2 est \&amp;quot;$2\&amp;quot;&lt;br /&gt;
echo le paramètre \$3 est \&amp;quot;$3\&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que fait-il ? Il affiche les uns après les autres les trois premiers paramètres du script, donc si l’on tape :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ./essai01 paramètre un&lt;br /&gt;
le paramètre $1 est &amp;quot;paramètre&amp;quot;&lt;br /&gt;
le paramètre $2 est &amp;quot;un&amp;quot;&lt;br /&gt;
le paramètre $3 est &amp;quot;&amp;quot;&lt;br /&gt;
$ _&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Donc, les variables &amp;lt;code&amp;gt;$1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;$2&amp;lt;/code&amp;gt;… &amp;lt;code&amp;gt;$9&amp;lt;/code&amp;gt; contiennent les « mots » numéro 1, 2… 9 de la ligne de commande. Attention : par « mot » on entend ensemble de caractères ne contenant pas de caractères de séparations. Les caractères de séparation sont l’espace, la tabulation, le retour chariot quand c’est possible et le point virgule.&lt;br /&gt;
&lt;br /&gt;
Vous avez sans doute remarqué que j’ai utilisé les caractères : &amp;lt;code&amp;gt;\$&amp;lt;/code&amp;gt; à la place de &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; ainsi que &amp;lt;code&amp;gt;\&amp;quot;&amp;lt;/code&amp;gt; à la place de &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt; dans le script. Pour quelle raison ? C’est simple : si l’on tape &amp;lt;code&amp;gt;echo &amp;quot;essai&amp;quot;&amp;lt;/code&amp;gt; on obtient : &amp;lt;code&amp;gt;essai&amp;lt;/code&amp;gt;, si l’on veut obtenir &amp;lt;code&amp;gt;&amp;quot;essai&amp;quot;&amp;lt;/code&amp;gt; il faut dire à &amp;lt;code&amp;gt;echo&amp;lt;/code&amp;gt; (en réalité, au shell qui va lancer &amp;lt;code&amp;gt;echo&amp;lt;/code&amp;gt;) que le caractère &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt; n’indique pas le début d&#039;une chaîne de caractère (comme c’est le comportement par défaut) mais que ce caractère fait partie de la chaîne : on dit que l’on « échappe » ou « protège » le caractère &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt; en tapant &amp;lt;code&amp;gt;\&amp;quot;&amp;lt;/code&amp;gt;. En « échappant » le caractère &amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt; (par &amp;lt;code&amp;gt;\\&amp;lt;/code&amp;gt;) on obtient le caractère &amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt; sans signification particulière. On peut dire que le caractère &amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt; devant un autre lui fait perdre sa signification particulière s’il en a une, ne fait rien si le caractère qui suit &amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt; n’en a pas.&lt;br /&gt;
&lt;br /&gt;
Maintenant, essayons de taper :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ./essai01 *&lt;br /&gt;
le paramètre $1 est &amp;quot;Mail&amp;quot;&lt;br /&gt;
le paramètre $2 est &amp;quot;essai01&amp;quot;&lt;br /&gt;
le paramètre $3 est &amp;quot;nsmail&amp;quot;&lt;br /&gt;
$ _&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le résultat doit être sensiblement différent sur votre machine : il dépend du contenu de votre répertoire courant. Que s’est-il passé ? Le &#039;&#039;shell&#039;&#039; a remplacé le caractère * par la liste de tous les fichiers non cachés présents dans le répertoire actif. En fait, toutes les substitutions du shell sont possibles ! Le &#039;&#039;shell&#039;&#039; qui substitue aux paramètres des valeurs étendues par les caractères spéciaux : * (toute suite de caractères) ? (un caractère quelconque), [dze] (l&#039;un des caractères d, z ou e), [d-z] (les caractères de &#039;d&#039; à &#039;z&#039;)…&lt;br /&gt;
&lt;br /&gt;
Autre exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ./essai01 \*&lt;br /&gt;
le paramètre $1 est &amp;quot;*&amp;quot;&lt;br /&gt;
le paramètre $2 est &amp;quot;&amp;quot;&lt;br /&gt;
le paramètre $3 est &amp;quot;&amp;quot;&lt;br /&gt;
$ _&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hé oui, on a « échappé » le caractère &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; donc il a perdu sa signification particulière : il est redevenu un simple &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
C’est bien, me direz vous, mais si je veux utiliser plus de dix paramètres ? Il faut utiliser les accolades : &amp;lt;code&amp;gt;${10}&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;${23}&amp;lt;/code&amp;gt; par exemple. On peut aussi utiliser la commande &amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; ; à titre d’exemple voici le script &amp;lt;code&amp;gt;essai02&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
echo le paramètre 1 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 2 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 3 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 4 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 5 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 6 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 7 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 8 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 9 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 10 est \&amp;quot;$1\&amp;quot;&lt;br /&gt;
shift&lt;br /&gt;
echo le paramètre 11 est \&amp;quot;$1\&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si vous tapez :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ./essai02 1 2 3 4 5 6 7 8 9 10 11 12 13&lt;br /&gt;
le paramètre 1 est &amp;quot;1&amp;quot;&lt;br /&gt;
le paramètre 2 est &amp;quot;2&amp;quot;&lt;br /&gt;
le paramètre 3 est &amp;quot;3&amp;quot;&lt;br /&gt;
le paramètre 4 est &amp;quot;4&amp;quot;&lt;br /&gt;
le paramètre 5 est &amp;quot;5&amp;quot;&lt;br /&gt;
le paramètre 6 est &amp;quot;6&amp;quot;&lt;br /&gt;
le paramètre 7 est &amp;quot;7&amp;quot;&lt;br /&gt;
le paramètre 8 est &amp;quot;8&amp;quot;&lt;br /&gt;
le paramètre 9 est &amp;quot;9&amp;quot;&lt;br /&gt;
le paramètre 10 est &amp;quot;10&amp;quot;&lt;br /&gt;
le paramètre 11 est &amp;quot;11&amp;quot;&lt;br /&gt;
$ _&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À chaque appel de &amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; les paramètres sont décalés d’un numéro : le paramètre 2 devient le paramètre 1, 3 devient 2, etc.&lt;br /&gt;
Évidemment le paramètre 1 est perdu par l’appel de &amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; : vous devez donc vous en servir avant d’appeler &amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; (ou le sauvegarder dans une variable).&lt;br /&gt;
&lt;br /&gt;
=== Les variables ===&lt;br /&gt;
&lt;br /&gt;
Le passage des paramètres nous a montré l&#039;utilisation de &amp;quot;noms&amp;quot; particuliers : &amp;lt;code&amp;gt;$1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;$2&amp;lt;/code&amp;gt; etc. Ce sont les substitutions des variables &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt;, etc. par leur valeurs. Mais vous pouvez définir et utiliser n&#039;importe quel nom. Attention toutefois à ne pas confondre le nom d&#039;une variable (notée par exemple &amp;lt;code&amp;gt;machin&amp;lt;/code&amp;gt;) et son contenu (noté dans notre cas &amp;lt;code&amp;gt;$machin&amp;lt;/code&amp;gt;). Vous connaissez peut-être la variable &amp;lt;code&amp;gt;PATH&amp;lt;/code&amp;gt; (attention, le shell différencie les majuscules des minuscules) qui contient la liste des répertoires (séparés par des &amp;lt;code&amp;gt;&amp;quot;:&amp;quot;&amp;lt;/code&amp;gt;) dans lesquels il doit rechercher les programmes. Si dans un script vous tapez :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;1:#!/bin/sh&lt;br /&gt;
2:PATH=/bin # PATH contient /bin&lt;br /&gt;
3:PATH=PATH:/usr/bin # PATH contient PATH:/usr/bin&lt;br /&gt;
4:PATH=/bin # PATH contient /bin&lt;br /&gt;
5:PATH=&amp;quot;$PATH:/usr/bin&amp;quot; # PATH contient /bin:/usr/bin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les numéros ne sont là que pour repérer les lignes, il ne faut pas les taper. La ligne 3 est très certainement une erreur, à gauche du signe &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt; il faut une variable (donc un nom sans &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) mais à droite de ce même signe il faut une valeur, et la valeur que l&#039;on a mise est &amp;lt;code&amp;gt;PATH:/usr/bin&amp;lt;/code&amp;gt; : il n&#039;y a aucune substitution à faire. Par contre la ligne 5 est certainement correcte : à droite du &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt; on a mis &amp;lt;code&amp;gt;&amp;quot;$PATH:/usr/bin&amp;quot;&amp;lt;/code&amp;gt;, la valeur de &amp;lt;code&amp;gt;$PATH&amp;lt;/code&amp;gt; étant &amp;lt;code&amp;gt;/bin&amp;lt;/code&amp;gt;, la valeur après substitution par le shell de &amp;lt;code&amp;gt;&amp;quot;$PATH:/usr/bin&amp;quot;&amp;lt;/code&amp;gt; est &amp;lt;code&amp;gt;/bin:/usr/bin&amp;lt;/code&amp;gt;. Donc, à la fin de la ligne 5, la valeur de la variable &amp;lt;code&amp;gt;PATH&amp;lt;/code&amp;gt; est &amp;lt;code&amp;gt;&amp;quot;/bin:/usr/bin&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Attention : les caractères spéciaux (espaces, &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt;, ...) ne peuvent pas apparaitre à gauche du signe &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt;, et doivent être précédés d&#039;un &amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt; ou mis entre guillemets à droite du signe &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Résumons&amp;lt;/u&amp;gt; : &amp;lt;code&amp;gt;MACHIN&amp;lt;/code&amp;gt; est un nom de variable que l&#039;on utilise lorsque l&#039;on a besoin d&#039;un nom de variable (mais pas de son contenu), et &amp;lt;code&amp;gt;$MACHIN&amp;lt;/code&amp;gt; est le contenu de la variable &amp;lt;code&amp;gt;MACHIN&amp;lt;/code&amp;gt; que l&#039;on utilise lorsque l&#039;on a besoin du contenu de cette variable.&lt;br /&gt;
&lt;br /&gt;
=== Variables particulières ===&lt;br /&gt;
&lt;br /&gt;
Il y a un certain nombre de variables particulières, en voici quelques unes :&lt;br /&gt;
&lt;br /&gt;
* la variable &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt; (dont le contenu est &amp;lt;code&amp;gt;$@&amp;lt;/code&amp;gt;) contient l&#039;ensemble de tous les &amp;quot;mots&amp;quot; qui on été passé au script (c&#039;est à dire toute la ligne de commande, sans le nom du script). On l&#039;utilise en général avec des guillemets : &amp;lt;code&amp;gt;&amp;quot;$@&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* la variable &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt; contient le nombre de paramètres (&amp;lt;code&amp;gt;$#&amp;lt;/code&amp;gt;) qui ont été passés au programme.&lt;br /&gt;
* la variable &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (zéro) contient le nom du script (ou du lien si le script a été appelé depuis un lien).&lt;br /&gt;
&lt;br /&gt;
Il y en a d&#039;autres, moins utilisées : allez voir la man page de &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Saisir la valeur d&#039;une variable ===&lt;br /&gt;
&lt;br /&gt;
Les paramètres permettent à l&#039;utilisateur d&#039;agir sur le déroulement du script avant son exécution. Mais il est aussi souvent intéressant de pouvoir agir sur le déroulement du script lors de son exécution, c&#039;est ce que permet la commande : &amp;lt;code&amp;gt;read nom_variable&amp;lt;/code&amp;gt;. Dans cette commande vous pouvez bien sûr remplacer nom_variable par le nom de variable qui vous convient le mieux. Voici un exemple simple.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
echo -n &amp;quot;Entrez votre prénom : &amp;quot;&lt;br /&gt;
read prenom&lt;br /&gt;
echo -n &amp;quot;Entrez votre nom de login : &amp;quot;&lt;br /&gt;
read nomlogin&lt;br /&gt;
echo &amp;quot;Le nom de login de $prenom est $nomlogin.&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce script se déroule ainsi :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ./essai02bis&lt;br /&gt;
Entrez votre prénom : Marc&lt;br /&gt;
Entrez votre nom de login : spoutnik&lt;br /&gt;
Le nom de login de Marc est spoutnik.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lors du déroulement du script vous devez valider vos entrées en appuyant sur la touche &amp;quot;Entrée&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
L&#039;option &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; de &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; permet de masquer la saisie. Par exemple &amp;lt;code&amp;gt;read -s pass&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Arithmétique ===&lt;br /&gt;
&lt;br /&gt;
Vous vous doutez bien qu&#039;il est possible de faire des calculs avec le shell. En fait, le shell ne &amp;quot;sait&amp;quot; faire que des calculs sur les nombres entiers (ceux qui n&#039;ont pas de virgules ;-). Pour faire un calcul il faut encadrer celui-ci de : &amp;lt;code&amp;gt;$(( un calcul ))&amp;lt;/code&amp;gt;. Exemple, le script essai03 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
echo 2+3*5 = $((2+3*5))&lt;br /&gt;
MACHIN=12&lt;br /&gt;
echo MACHIN*4 = $(($MACHIN*4))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Affichera :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ./essai03&lt;br /&gt;
2+3*5 = 17&lt;br /&gt;
MACHIN*4 = 48&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vous remarquerez que le shell respecte les priorités mathématiques habituelles (il fait les multiplications avant les additions !). L&#039;opérateur puissance est &amp;lt;code&amp;gt;&amp;quot;**&amp;quot;&amp;lt;/code&amp;gt; (ie : 2 puissance 5 s&#039;écrit : &amp;lt;code&amp;gt;2**5&amp;lt;/code&amp;gt;). On peut utiliser des parenthèses pour modifier l&#039;ordre des calculs.&lt;br /&gt;
&lt;br /&gt;
== Guillemets, échappement, ... ==&lt;br /&gt;
&lt;br /&gt;
Nous avons vu plus haut qu&#039;écrire par exemple &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; ou&lt;br /&gt;
&amp;lt;code&amp;gt;\*&amp;lt;/code&amp;gt; étaient différents. En fait, la plupart des caractères&lt;br /&gt;
autres que des chiffres ou des lettres ont une signification&lt;br /&gt;
particulière pour le shell.&lt;br /&gt;
&lt;br /&gt;
Pour exécuter une commande, le shell commence par regarder tous ces&lt;br /&gt;
caractères particuliers. Il fait en particulier les choses suivantes&lt;br /&gt;
(dans cet ordre) :&lt;br /&gt;
&lt;br /&gt;
* Expansion des variables (par exemple, dans &amp;lt;code&amp;gt;echo $var&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;$var&amp;lt;/code&amp;gt; sera remplacé par sa valeur),&lt;br /&gt;
&lt;br /&gt;
* Découpage de la ligne de commande selon les blancs (par exemple, la commande &amp;lt;code&amp;gt;echo un deux trois&amp;lt;/code&amp;gt; sera découpée en une commande &amp;lt;code&amp;gt;echo&amp;lt;/code&amp;gt; avec les trois arguments &amp;lt;code&amp;gt;un&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;deux&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;trois&amp;lt;/code&amp;gt;, alors que &amp;lt;code&amp;gt;echo &amp;quot;un deux trois&amp;quot;&amp;lt;/code&amp;gt;, avec des guillemets en plus, sera découpée en une commande &amp;lt;code&amp;gt;echo&amp;lt;/code&amp;gt; avec un seul argument &amp;lt;code&amp;gt;un deux trois&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* Expansion des jokers (&amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; remplacé par la liste des fichiers non cachés dans le répertoire courrant, &amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt;, ...)&lt;br /&gt;
&lt;br /&gt;
Pour éviter ce traitement spécial pour les caractères spéciaux, on a plusieurs solutions :&lt;br /&gt;
&lt;br /&gt;
* Précéder le caractère par un anti-slash : &lt;br /&gt;
&amp;lt;code&amp;gt;echo \*        # affiche une étoile&lt;br /&gt;
echo \$        # affiche un dollar&lt;br /&gt;
cat fichier\ avec\ espaces  # affiche le contenu du fichier &amp;quot;fichier avec espaces&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Mettre toute une chaine entre guillemets simples (apostrophes). Dans ce cas, seul le guillemet reste un caractère spécial (pour terminer la chaine) :&lt;br /&gt;
&amp;lt;code&amp;gt;echo &#039;*&#039;       # affiche une étoile&lt;br /&gt;
echo &#039;$&#039;       # affiche un dollar&lt;br /&gt;
cat &#039;fichier avec espaces&#039;  # affiche le contenu du fichier &amp;quot;fichier avec espaces&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Mettre toute une chaine entre guillemets doubles. Dans ce cas, les caractères &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt; restent actifs :&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;*&amp;quot;       # affiche une étoile&lt;br /&gt;
var=toto&lt;br /&gt;
echo &amp;quot;$var&amp;quot;       # affiche &amp;quot;toto&amp;quot;&lt;br /&gt;
f=fichier&lt;br /&gt;
e=espaces&lt;br /&gt;
cat &amp;quot;$f avec $e&amp;quot;  # affiche le contenu du fichier &amp;quot;fichier avec espaces&amp;quot;&lt;br /&gt;
echo &amp;quot;\$f avec $e&amp;quot; # affiche &amp;quot;$f avec espaces&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il reste un autre type de guillemets, le guillemet inversé (backquote en anglais) : &amp;lt;code&amp;gt;`&amp;lt;/code&amp;gt;. Quand le shell rencontre une chaine du type &amp;lt;code&amp;gt;`commande`&amp;lt;/code&amp;gt;, il exécute &amp;lt;code&amp;gt;commande&amp;lt;/code&amp;gt;, et remplace la chaine par le résultat de la commande. Par exemple : &lt;br /&gt;
&amp;lt;code&amp;gt;ancienne_date=`date`&lt;br /&gt;
sleep 3&lt;br /&gt;
echo &amp;quot;La date est maintenant :&amp;quot;&lt;br /&gt;
date&lt;br /&gt;
echo &amp;quot;Mais tout à l&#039;heure, il était : $ancienne_date&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note : à la place de &amp;lt;code&amp;gt;`commande`&amp;lt;/code&amp;gt;, on peut aussi écrire&lt;br /&gt;
&amp;lt;code&amp;gt;$(commande)&amp;lt;/code&amp;gt;, qui est plutôt plus lisible, et plus&lt;br /&gt;
portable.&lt;br /&gt;
&lt;br /&gt;
== Les instructions de contrôle de scripts ==&lt;br /&gt;
&lt;br /&gt;
Les instructions de contrôle du shell permettent de modifier l&#039;exécution purement séquencielle d&#039;un script. Jusqu&#039;à maintenant, les scripts que nous avons créés n&#039;étaient pas très complexes. Ils ne pouvaient de toute façon pas l&#039;être car nous ne pouvions pas modifier l&#039;ordre des instructions, ni en répéter.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;exécution conditionnelle ===&lt;br /&gt;
&lt;br /&gt;
Lorsque vous programmerez des scripts, vous voudrez que vos scripts fassent une chose si une certaine condition est remplie et autre chose si elle ne l&#039;est pas. La construction de bash qui permet cela est le fameux test : &amp;lt;code&amp;gt;if then else fi&amp;lt;/code&amp;gt;. Sa syntaxe est la suivante (la partie &amp;lt;code&amp;gt;else...&amp;lt;/code&amp;gt; est optionnelle) :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;if &amp;lt;test&amp;gt; ; &lt;br /&gt;
then&lt;br /&gt;
   &amp;lt;instruction 1&amp;gt;&lt;br /&gt;
   &amp;lt;instruction 2&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;instruction n&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
   &amp;lt;instruction n+1&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;instruction n+p&amp;gt;&lt;br /&gt;
fi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut savoir que tous les programmes renvoient une valeur. Cette valeur est stockée dans la variable &amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt; dont la valeur est, rappelons le : &amp;quot;&amp;lt;code&amp;gt;$?&amp;lt;/code&amp;gt;&amp;quot;. Pour le shell une valeur nulle est synonyme de VRAI et une valeur non nulle est synonyme de FAUX. Ceci parce que, en général les programmes renvoie zéro quand tout c&#039;est bien passé et un code d&#039;erreur (nombre non nul) quand il s&#039;en est produit une.&lt;br /&gt;
&lt;br /&gt;
Il existe deux programmes particuliers : &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; renvoie toujours 0 et &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; renvoie toujours 1. Sachant cela, voyons ce que fait le programme suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
if true ; &lt;br /&gt;
then &lt;br /&gt;
   echo Le premier test est VRAI($?)&lt;br /&gt;
else&lt;br /&gt;
   echo Le premier test est FAUX($?)&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if false ;&lt;br /&gt;
then&lt;br /&gt;
   echo Le second test est VRAI($?)&lt;br /&gt;
else&lt;br /&gt;
   echo Le second test est FAUX($?)&lt;br /&gt;
fi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Affichera :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ./test&lt;br /&gt;
Le premier test est VRAI(0)&lt;br /&gt;
Le second test est FAUX(1)&lt;br /&gt;
$ _&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On peut donc conclure que l&#039;instruction &amp;lt;code&amp;gt;if ... then ... else ... fi&amp;lt;/code&amp;gt;, fonctionne de la manière suivante : si (&#039;&#039;&#039;if&#039;&#039;&#039; en anglais) le test est VRAI(0) alors (&#039;&#039;&#039;then&#039;&#039;&#039; en anglais) le bloc d&#039;instructions compris entre le &amp;lt;code&amp;gt;then&amp;lt;/code&amp;gt; et le &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; (ou le &amp;lt;code&amp;gt;fi&amp;lt;/code&amp;gt; en l&#039;absence de &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt;) est exécuté, sinon (&#039;&#039;&#039;else&#039;&#039;&#039; en anglais) le test est FAUX(différent de 0)) et on exécute le bloc d&#039;instructions compris entre le &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; et le &amp;lt;code&amp;gt;fi&amp;lt;/code&amp;gt; si ce bloc existe.&lt;br /&gt;
&lt;br /&gt;
Bon, évidemment, des tests de cet ordre ne paraissent pas très utiles. Voyons maintenant de vrais tests.&lt;br /&gt;
&lt;br /&gt;
=== Les tests ===&lt;br /&gt;
&lt;br /&gt;
Un test, nous l&#039;avons vu, n&#039;est rien de plus qu&#039;une commande standard.&lt;br /&gt;
Une des commandes standard est &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt;, sa syntaxe est un&lt;br /&gt;
peu complexe, nous allons la décrire avec des exemples.&lt;br /&gt;
&lt;br /&gt;
* si l&#039;on veut tester l&#039;existence d&#039;un répertoire &amp;lt;code&amp;gt;&amp;lt;machin&amp;gt;&amp;lt;/code&amp;gt;, on tapera : &amp;lt;code&amp;gt;test -d &amp;lt;machin&amp;gt;&amp;lt;/code&amp;gt; (&#039;d&#039; comme &#039;&#039;&#039;&#039;&#039;d&#039;&#039;&#039;irectory&#039;&#039;)&lt;br /&gt;
* si l&#039;on veut tester l&#039;existence d&#039;un fichier &amp;lt;code&amp;gt;&amp;lt;machin&amp;gt;&amp;lt;/code&amp;gt;, on tapera : &amp;lt;code&amp;gt;test -f &amp;lt;machin&amp;gt;&amp;lt;/code&amp;gt; (&#039;f&#039; comme &#039;&#039;&#039;&#039;&#039;f&#039;&#039;&#039;ile&#039;&#039;)&lt;br /&gt;
* si l&#039;on veut tester l&#039;existence d&#039;un fichier ou répertoire &amp;lt;code&amp;gt;&amp;lt;machin&amp;gt;&amp;lt;/code&amp;gt;, on tapera : &amp;lt;code&amp;gt;test -e &amp;lt;machin&amp;gt;&amp;lt;/code&amp;gt; (&#039;e&#039; comme &#039;&#039;&#039;&#039;&#039;e&#039;&#039;&#039;xist&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Pour plus d&#039;information faites : &amp;lt;code&amp;gt;man test&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On peut aussi combiner deux tests par des opérations logiques : &#039;ou&#039; correspond à &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; (&#039;o&#039; comme &#039;&#039;&#039;&#039;&#039;&amp;lt;font size=&amp;quot;+1&amp;quot;&amp;gt;o&amp;lt;/font&amp;gt;&#039;&#039;&#039;r&#039;&#039;), &#039;et&#039; correspond à &amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt; (&#039;a&#039; comme &#039;&#039;&#039;&#039;&#039;&amp;lt;font size=&amp;quot;+1&amp;quot;&amp;gt;a&amp;lt;/font&amp;gt;&#039;&#039;&#039;nd&#039;&#039;) (à nouveau allez voir la man page), exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code multi&amp;gt;test -x /bin/sh -a -d /etc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette instruction teste l&#039;existence de l&#039;éxécutable &amp;lt;code&amp;gt;/bin/sh&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-x /bin/sh&amp;lt;/code&amp;gt;) et (&amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt;) la présence d&#039;un répertoire &amp;lt;code&amp;gt;/etc&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-d /etc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
On peut remplacer la commande &amp;lt;code&amp;gt;test &amp;lt;un test&amp;gt;&amp;lt;/code&amp;gt; par &amp;lt;code&amp;gt;[ &amp;lt;un test&amp;gt; ]&amp;lt;/code&amp;gt; qui est plus lisible, exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;if [ -x /bin/sh ] ; then&lt;br /&gt;
# (&#039;x&#039; comme &amp;quot;e_x_ecutable&amp;quot;)&lt;br /&gt;
  echo &amp;quot;/bin/sh est exécutable. C&#039;est bien.&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
  echo &amp;quot;/bin/sh n&#039;est pas exécutable.&amp;quot;&lt;br /&gt;
  echo &amp;quot;Votre système n&#039;est pas normal.&amp;quot;&lt;br /&gt;
fi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toujours avec les crochets de &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt;, si vous n&#039;avez qu&#039;une seule chose à faire en fonction du résultat d&#039;un test, alors vous pouvez utiliser la syntaxe suivante :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[ -x /bin/sh ] &amp;amp;&amp;amp; echo /bin/sh est exécutable.&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt; ou encore :&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;[ -x /bin/sh ] || echo &amp;quot;/bin/sh n&#039;est pas exécutable.&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;affichage du message est effectué, dans le premier cas que si le test est vrai et dans le second cas, que si le test est faux. Dans l&#039;exemple on teste si /bin/sh est un fichier exécutable.&amp;lt;br /&amp;gt; Cela allège le script sans pour autant le rendre illisible, si cette syntaxe est utilisée à bon escient.&lt;br /&gt;
&lt;br /&gt;
Mais il n&#039;y a pas que la commande &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt; qui peut être employée. Par exemple, la commande &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt; renvoie 0 quand la recherche a réussi et 1 quand la recherche a échoué. &amp;lt;br /&amp;gt;Par exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;if grep -E &amp;quot;^frederic:&amp;quot; /etc/passwd &amp;gt; /dev/null ; then&lt;br /&gt;
   echo L&#039;utilisateur frederic existe.&lt;br /&gt;
else&lt;br /&gt;
   echo L&#039;utilisateur frederic n&#039;existe pas.&lt;br /&gt;
fi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette série d&#039;instruction teste la présence de l&#039;utilisateur &amp;lt;code&amp;gt;frederic&amp;lt;/code&amp;gt; dans le fichier &amp;lt;code&amp;gt;/etc/passwd&amp;lt;/code&amp;gt;. Vous remarquerez que l&#039;on a fait suivre la commande &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt; d&#039;une redirection vers &amp;lt;code&amp;gt;/dev/null&amp;lt;/code&amp;gt; pour que le résultat de cette commande ne soit pas affiché : c&#039;est une utilisation classique. Ceci explique aussi l&#039;expression : &amp;quot;Ils sont tellement intéressants, tes mails, que je les envoie vers /dev/null&amp;quot; ;-).&lt;br /&gt;
&lt;br /&gt;
=== Faire quelque chose de différent suivant la valeur d&#039;une variable ===&lt;br /&gt;
&lt;br /&gt;
L&#039;instruction &amp;lt;code&amp;gt;case ... esac&amp;lt;/code&amp;gt; permet de modifier le déroulement du script selon la valeur d&#039;un paramètre ou d&#039;une variable. On l&#039;utilise le plus souvent quand les valeurs possibles sont en nombre restreint et peuvent être prévues. Les imprévus peuvent alors être représentés par le signe *. Demandons par exemple à l&#039;utilisateur s&#039;il souhaite afficher ou non les fichiers cachés du répertoire en cours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
# pose la question et récupère la réponse&lt;br /&gt;
echo &amp;quot;Le contenu du répertoire courant va être affiché.&amp;quot;&lt;br /&gt;
echo -n &amp;quot;Souhaitez-vous afficher aussi les fichiers cachés (oui/non) : &amp;quot;&lt;br /&gt;
read reponse&lt;br /&gt;
# agit selon la réponse&lt;br /&gt;
case $reponse in&lt;br /&gt;
   oui)&lt;br /&gt;
     clear&lt;br /&gt;
     ls -a;;&lt;br /&gt;
   non)&lt;br /&gt;
     ls;;&lt;br /&gt;
   *) echo &amp;quot;Erreur, vous deviez répondre par oui ou par non.&amp;quot;;;&lt;br /&gt;
esac&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seules les réponses &amp;quot;oui&amp;quot; et &amp;quot;non&amp;quot; sont réellement attendues dans ce script, toute autre réponse engendrera le message d&#039;erreur. On notera qu&#039;ici l&#039;écran est effacé avant l&#039;affichage dans le cas d&#039;une réponse positive, mais pas dans celui d&#039;une réponse négative. Lorsque vous utilisez l&#039;instruction &amp;lt;code&amp;gt;case ... esac&amp;lt;/code&amp;gt;, faites bien attention de ne pas oublier les doubles points-virgules terminant les instructions de chacun des cas envisagés.&lt;br /&gt;
&lt;br /&gt;
=== Faire la même chose pour tous les éléments d&#039;une liste ===&lt;br /&gt;
&lt;br /&gt;
Lorsqu&#039;on programme, on est souvent amené à faire la même chose &#039;&#039;&#039;pour tous&#039;&#039;&#039; les élément d&#039;une liste. Dans un shell script, il est bien évidemment possible de ne pas réécrire dix fois la même chose. On dira que l&#039;on fait une boucle. L&#039;instruction qui réalise une boucle est&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;for &amp;lt;variable&amp;gt; in &amp;lt;liste de valeurs pour la variable&amp;gt; ; do&lt;br /&gt;
   &amp;lt;instruction 1&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;instruction n&amp;gt;&lt;br /&gt;
done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Voyons comment ça fonctionne. Supposons que nous souhaitions renommer tous nos fichiers *.tar.gz en *.tar.gz.old, nous taperons le script suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
# x prend chacune des valeurs possibles correspondant&lt;br /&gt;
# au motif : *.tar.gz&lt;br /&gt;
for x in ./*.tar.gz ; do&lt;br /&gt;
   # tous les fichiers $x sont renommés $x.old&lt;br /&gt;
   echo &amp;quot;$x -&amp;gt; $x.old&amp;quot;&lt;br /&gt;
   mv &amp;quot;$x&amp;quot; &amp;quot;$x.old&amp;quot;&lt;br /&gt;
   # on finit notre boucle&lt;br /&gt;
done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple, non ? Un exemple plus complexe ? Supposons que nous voulions parcourir tous les sous-répertoires du répertoire courant pour faire cette même manipulation. Nous pourrons taper :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; 1:#!/bin/sh&lt;br /&gt;
2:for REP in `find -type d` ; do&lt;br /&gt;
3:   for FICH in &amp;quot;$REP/*.tar.gz&amp;quot; ; do&lt;br /&gt;
4:      if [ -f &amp;quot;$FICH&amp;quot; ] ; then&lt;br /&gt;
5:         mv &amp;quot;$FICH&amp;quot; &amp;quot;$FICH.old&amp;quot;&lt;br /&gt;
6:      else&lt;br /&gt;
7:         echo &amp;quot;On ne renomme pas $FICH car ce n&#039;est pas un fichier&amp;quot;&lt;br /&gt;
8:      fi&lt;br /&gt;
9:   done&lt;br /&gt;
10:done&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Explications&amp;lt;/u&amp;gt; : dans le premier &#039;for&#039;, on a précisé comme liste : &amp;lt;code&amp;gt;`find -type d`&amp;lt;/code&amp;gt; (attention au sens des apostrophes, sur un clavier azerty français, on obtient ce symbole en appuyant sur &amp;lt;code&amp;gt;ALTGR+è&amp;lt;/code&amp;gt;, ce ne sont pas des simples quotes &#039;). &amp;lt;br /&amp;gt;Lorsque l&#039;on tape une commande entre apostrophes inverses, le shell exécute d&#039;abord cette commande, et remplace l&#039;expression entre apostrophes inverses par la sortie standard de cette commande (ce qu&#039;elle affiche à l&#039;écran). Donc, dans le cas qui nous intéresse, la liste est le résultat de la commande &amp;lt;code&amp;gt;find -type d&amp;lt;/code&amp;gt;, c&#039;est à dire la liste de tous les sous-répertoires du répertoire courant. &amp;lt;br /&amp;gt;Ainsi, en ligne 2, on fait prendre à la variable REP le nom de chacun des sous-répertoires du répertoire courant, puis (en ligne 3) on fait prendre à la variable FICH le nom de chacun des fichiers .tar.gz de $REP (un des sous-répertoires), puis si $FICH est un fichier, on le renomme, sinon on affiche un avertissement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;note&amp;lt;/u&amp;gt; : ce script ne marchera pas si des noms de répertoires contiennent des espaces : dans ce cas, &amp;lt;code&amp;gt;`find -type d`&amp;lt;/code&amp;gt; sera exécuté, remplacé par son résultat, et ensuite découpé selon les blancs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Remarque&amp;lt;/u&amp;gt; : ce n&#039;est pas le même fonctionnement que la boucle &amp;lt;code&amp;gt;for&amp;lt;/code&amp;gt; d&#039;autres langage (le pascal, le C ou le basic par exemple).&lt;br /&gt;
&lt;br /&gt;
=== Faire une même chose tant qu&#039;un certaine condition est remplie ===&lt;br /&gt;
&lt;br /&gt;
Pour faire une certaine chose &#039;&#039;&#039;tant qu&#039;&#039;&#039;&#039;une condition est remplie, on utilise un autre type de boucle :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;while &amp;lt;un test&amp;gt; ; do&lt;br /&gt;
   &amp;lt;instruction 1&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;instruction n&amp;gt;&lt;br /&gt;
done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Supposons, par exemple que vous souhaitiez afficher les 100 premiers nombres (pour une obscure raison), alors vous taperez :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;i=0&lt;br /&gt;
while [ $i -lt 100 ] ; do&lt;br /&gt;
   echo $i&lt;br /&gt;
   i=$[$i+1]&lt;br /&gt;
done&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Remarque&amp;lt;/u&amp;gt; : &amp;lt;code&amp;gt;-lt&amp;lt;/code&amp;gt; signifie &amp;quot;&#039;&#039;&#039;l&#039;&#039;&#039;esser &#039;&#039;&#039;t&#039;&#039;&#039;han&amp;quot; ou &amp;quot;plus petit que&amp;quot; (et &amp;lt;code&amp;gt;-gt&amp;lt;/code&amp;gt; signifie &amp;quot;plus grand&amp;quot;, ou &amp;quot;&#039;&#039;&#039;g&#039;&#039;&#039;reater &#039;&#039;&#039;t&#039;&#039;&#039;han&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Ici, on va afficher le contenu de &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; et lui ajouter 1 tant que &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; sera (&amp;lt;code&amp;gt;-lt&amp;lt;/code&amp;gt;) plus petit que 100. Remarquez que 100 ne s&#039;affiche pas, car &amp;lt;code&amp;gt;-lt&amp;lt;/code&amp;gt; est &amp;quot;plus petit&amp;quot;, mais pas &amp;quot;plus petit ou égal&amp;quot; (dans ce cas, utilisez &amp;lt;code&amp;gt;-le&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;-ge&amp;lt;/code&amp;gt; pour &amp;quot;plus grand ou égal&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== Refaire à un autre endroit la même chose ===&lt;br /&gt;
&lt;br /&gt;
Souvent, vous voudrez refaire ce que vous venez de taper autre part&lt;br /&gt;
dans votre script. Dans ce cas il est inutile de retaper la même&lt;br /&gt;
chose, préférez utiliser des fonctions qui permettent de réutiliser&lt;br /&gt;
une portion de script. Voyons un exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/bin/sh&lt;br /&gt;
addpath ()&lt;br /&gt;
{&lt;br /&gt;
   if echo $PATH | grep -v $1 &amp;gt;/dev/null; then&lt;br /&gt;
      PATH=$PATH:$1;&lt;br /&gt;
   fi;&lt;br /&gt;
   PATH=`echo $PATH|sed s/::/:/g`&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
addpath /opt/apps/bin&lt;br /&gt;
addpath /opt/office52/program&lt;br /&gt;
addpath /opt/gnome/bin&lt;br /&gt;
export PATH&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Au début, nous avons défini une fonction nommée &amp;lt;code&amp;gt;addpath&amp;lt;/code&amp;gt; dont le but est d&#039;ajouter le premier argument (&amp;lt;code&amp;gt;$1&amp;lt;/code&amp;gt;) de la fonction &amp;lt;code&amp;gt;addpath&amp;lt;/code&amp;gt; à la variable &amp;lt;code&amp;gt;PATH&amp;lt;/code&amp;gt; si ce premier argument n&#039;est pas déjà présent (&amp;lt;code&amp;gt;grep -v $1&amp;lt;/code&amp;gt;) dans la variable &amp;lt;code&amp;gt;PATH&amp;lt;/code&amp;gt;, ainsi que supprimer les chemins vides (&amp;lt;code&amp;gt;sed s/::/:/g&amp;lt;/code&amp;gt;) de PATH. &amp;lt;br /&amp;gt;Ensuite, nous exécutons cette fonction pour trois arguments : /opt/apps/bin, /opt/office52/bin et /opt/gnome/bin.&lt;br /&gt;
&lt;br /&gt;
En fait, une fonction est seulement un script écrit à l&#039;intérieur d&#039;un script. Les fonctions permettent surtout de ne pas multiplier les petits scripts, ainsi que de partager des variables sans se préoccuper de la clause &amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; mais cela constitue une utilisation avancée du shell, nous n&#039;irons pas plus loin dans cet article.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Remarque&amp;lt;/u&amp;gt; : on peut aussi utiliser le mot clé&lt;br /&gt;
&amp;lt;code&amp;gt;function&amp;lt;/code&amp;gt;, mais cette syntaxe n&#039;est pas supportée par tous&lt;br /&gt;
les shells, et n&#039;est donc pas portable :&lt;br /&gt;
&amp;lt;code&amp;gt;function addpath ()&lt;br /&gt;
{&lt;br /&gt;
# ...&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Autres types de répétitions. ===&lt;br /&gt;
&lt;br /&gt;
Il existe d&#039;autres types de répétitions, mais nous ne nous en occuperons pas dans cet article, je vous conseille la lecture, forcément profitable, de la &amp;quot;man page&amp;quot; de bash (&amp;lt;code&amp;gt;man bash&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
À vous de jouer !&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;merci&amp;quot;&amp;gt;Cette page est issue de la documentation &#039;pré-wiki&#039; de Léa a été convertie avec HTML::WikiConverter. Elle fut créée par Frédéric Bonnaud le 29/08/2000.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Copy|29/08/2000|[[Utilisateur:Fred|Fred]], Marc|CC-BY-NC-SA}}&lt;br /&gt;
&lt;br /&gt;
=Autres ressources=&lt;br /&gt;
* [http://jipe.homelinux.org/trucs_bash.html Pour aller plus loin...] (des trucs et astuces pour bash)&lt;br /&gt;
* [http://abs.traduc.org/abs-4.2.01-fr/ Aller à 100%] (Guide avancé d&#039;écriture des scripts Bash)&lt;br /&gt;
* [http://download.gna.org/unix-initiation/ Introduction à Unix et à la programmation Shell] (cours sur Unix de l&#039;école d&#039;ingénieur de l&#039;ESME SUDRIA, publié sur [http://gna.org])&lt;br /&gt;
* [http://cours.enise.fr/info/unix/ Tout ce que vous avez toujours voulu savoir sur Unix] (cours de l&#039;Énise)&lt;/div&gt;</summary>
		<author><name>Helix</name></author>
	</entry>
</feed>