tuteurs.ens.fr/unix/shell.tml

740 lines
21 KiB
Text
Raw Normal View History

2002-11-23 16:58:15 +01:00
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html
PUBLIC "-//ENS/Tuteurs//DTD TML 1//EN"
"tuteurs://DTD/tml.dtd">
<html>
<head>
<title>Shell</title>
</head>
<body>
<h1>Le shell</h1>
<h2><a name="presentation">Pr<50>sentation</a></h2>
<p>
Le machin qui interpr<70>te les commandes.
</p>
<h3><a name="path">Comment le shell trouve-t-il les commandes<65>?</a>
</h3>
<p>
La <a href="#variable">variable</a> <code>PATH</code> contient le chemin d'acc<63>s
aux commandes. Le shell l'utilise pour trouver les commandes. Il s'agit d'une
liste de r<>pertoires s<>par<61>s par des <code>:</code>. La plupart des commandes
sont en fait des programmes, c'est-<2D>-dire des fichiers qu'on trouve dans le
syst<EFBFBD>me de fichiers.
</p>
<p>
Par exemple, quand vous tapez <code>ls</code>, le shell ex<65>cute le fichier
<code>/bin/ls</code>. Pour trouver ce fichier, il cherche dans le premier
r<EFBFBD>pertoire du <code>PATH</code> un fichier qui s'appelle <code>ls</code>.
S'il ne trouve pas, il cherche ensuite dans le deuxi<78>me r<>pertoire et ainsi
de suite.
</p>
<p>
S'il ne trouve la commande dans aucun r<>pertoire du <code>PATH</code>, le shell
affiche un message d'erreur. Exemple:
</p>
<pre>
<span class="prompt">chaland ~ $</span> sl
sl: Command not found</pre>
<h3><a name="builtins">Commandes internes</a></h3>
<p>
Certaines commandes du shell ne sont pas des programmes mais des commandes
<em>internes</em> (<em>builtins functions</em>). Elles sont directement
reconnues et ex<65>cut<75>es par le shell. Un exemple de commande interne est
<code>cd</code>. C'est le r<>pertoire courant du shell qui est modifi<66> par
<code>cd</code>, ce qui signifie que le script suivant<6E>:
</p>
<pre>
#! /bin/sh
cd $*</pre>
<p class="continue">
ne marche pas, car le shell lance un autre shell pour ex<65>cuter le script.
C'est ce sous-shell qui change son r<>pertoire courant, et ce changement est
perdu quand le sous-shell meurt.
</p>
<h3><a name="prog">Quels programmes utilisent le langage du shell<6C>?</a></h3>
<p>
Scripts pour automatiser ou syst<73>matiser des t<>ches,
op<EFBFBD>rations un peu compliqu<71>es.
</p>
<p>
sh<EFBFBD>: .profile (shell de login)<29>; sh lance un autre shell qui prend la rel<65>ve
pour la session.
.xinitrc (pour lancer X)
</p>
<p>
Il existe un script sp<73>cial, qui est ex<65>cut<75> au moment o<> on se connecte. Ce
script est contenu dans le fichier <code>$HOME/.profile</code>. C'est ce
fichier qui vous dit s'il y a de nouveaux messages dans forum, si vous avez
du courrier, etc.
</p>
<p>
Ce fichier est normalement mis <20> jour automatiquement par les scripts de la
config conscrits. Il est n<>anmoins possible de le modifier pour changer des
options.
</p>
<h2><a name="ligne">La ligne de commande</a></h2>
<h3><a name="raccourcis">Raccourcis pour les noms de fichiers</a></h3>
<p>
Il est parfois ennuyeux d'avoir <20> taper un nom complet de fichier comme
<code>nabuchodonosor</code>. Il est encore plus ennuyeux d'avoir <20> taper une
liste de fichier pour les donner en arguments <20> une commande, comme<6D>:
</p>
<pre>cc -o foo bar.c gee.c buz.c gog.c</pre>
<p>
Pour <20>viter ces probl<62>mes, on peut utiliser des <em>jokers</em>
(<em>wildcards</em> en anglais).
</p>
<h4>L'<27>toile</h4>
<p>
Une <strong><3E>toile</strong> <code>*</code> dans un nom de fichier est
interpr<EFBFBD>t<EFBFBD>e par le shell comme <20><>n'importe quelle s<>quence de
caract<EFBFBD>res<EFBFBD><EFBFBD> (mais <20>a ignore les fichiers dont le nom commence par un
point). Exemple:
</p>
<pre>cc -o foo *.c</pre>
<p>
Pour interpr<70>ter l'<27>toile, le shell va faire la liste de tous les noms de
fichiers du r<>pertoire courant qui ne commencent pas par <code>.</code> et
qui finissent par <code>.c</code>. Ensuite, il remplace <code>*.c</code>
par cette liste (tri<72>e par ordre alphab<61>tique) dans la ligne de commande, et
ex<EFBFBD>cute le r<>sultat, c'est-<2D>-dire par exemple<6C>:
</p>
<pre>cc -o foo bar.c buz.c foo.c gee.c gog.c</pre>
<h4>Le point d'interrogation</h4>
<p>
On a aussi le<strong>point d'interrogation</strong> <code>?</code>, qui
remplace un (et exactement un) caract<63>re quelconque (sauf un point en d<>but
de nom). Par exemple, <code>ls *.?</code> liste tous les dont l'extension
ne comporte qu'un caract<63>re (<code>.c</code>, <code>.h</code>...).
</p>
<h4>Les crochets</h4>
<p>
La forme <code>[abcd]</code> remplace un caract<63>re quelconque parmi
<code>a</code>, <code>b</code>, <code>c</code>, <code>d</code>. Enfin,
<code>[^abcd]</code> remplace un
caract<EFBFBD>re quelconque qui ne se trouve pas parmi <code>a</code>, <code>b</code>,
<code>c</code>, <code>d</code>.
</p>
<h4>Exemple</h4>
<pre>echo /users/*</pre>
<p class="continue">
affiche <20> peu pr<70>s la m<>me chose que
</p>
<pre>ls /users</pre>
<p class="continue">
(La commande <code>echo</code> se contente d'afficher ses arguments.)
</p>
<p>
&icone.attention; Attention<6F>:
</p>
<ul>
<li>C'est le shell qui fait le remplacement des arguments contenant un joker.
On ne peut donc pas faire <code>mv *.c *.bak</code>, car le shell va passer <20>
<code>mv</code> les arguments <code>foo.c bar.c foo.bak bar.bak</code>, et
<code>mv</code> ne sait pas quel fichier remplacer.
</li>
<li>Attention aux espaces. Si vous tapez <code>rm * ~</code>, le shell remplace
l'<27>toile par la liste des fichiers pr<70>sents, et ils seront tous effac<61>s. Si
vous tapez <code>rm *~</code>, seuls les fichiers dont le nom finit par un tilde
seront effac<61>s.
</li>
</ul>
<p>
Interlude: comment effacer un fichier nomm<6D> <code>?*</code><3E>? On ne peut
pas taper <code>rm<72>?*</code> car le shell remplace <code>?*</code> par la
liste de tous les fichiers du r<>pertoire courant. On peut taper <code>rm -i
*</code> qui supprime tous les fichiers, mais en demandant confirmation <20>
chaque fichier. On r<>pond <code>n</code> <20> toutes les questions sauf
<code>rm: remove <20>?*</code>.
Autre m<>thode: utiliser les m<>canismes de quotation.
</p>
<h3><a name="quotation">Quotation</a></h3>
<p>
Avec tous ces caract<63>res sp<73>ciaux, comment faire pour passer des arguments
bizarres <20> une commande<64>? Par exemple, comment faire afficher un point
d'interrogation suivi d'une <20>toile et d'un dollar par <code>echo</code><3E>?
Le shell fournit des m<>canismes pour ce faire. Ce sont les
<em>quotations</em>.
</p>
<h4>Le backslash (<code>\</code>)</h4>
<p>
Il suffit de pr<70>c<EFBFBD>der un caract<63>re sp<73>cial d'un backslash, et le shell
remplace ces deux caract<63>res par le caract<63>re sp<73>cial seul. <20>videmment, le
backslash est lui-m<>me un caract<63>re sp<73>cial.
</p>
<p>
Exemples:
</p>
<pre>
<span class="prompt">chaland ~ $</span> echo \?\*\$
?*$
<span class="prompt">chaland ~ $</span> echo \\\?\\\*\\\$
\?\*\$</pre>
<h4>Les apostrophes ou simples quotes (<code>'</code>)</h4>
<p>
Un autre moyen est d'inclure une cha<68>ne de caract<63>res entre apostrophes
(simples quotes) <code>'</code>. Tout ce qui se trouve entre deux apostrophes
sera pass<73> tel quel par le shell <20> la commande.
Exemple:
</p>
<pre>
<span class="prompt">chaland ~ $</span> echo '$?*'
$?*</pre>
<h4>Les guillemets doubles ou doubles quotes (<code>"</code>)</h4>
<p>
Les guillemets se comportent comme les apostrophes, <20> une exception pr<70>s: les
dollars et les backslashes sont interpr<70>t<EFBFBD>s entre les guillemets. Exemple:
</p>
<pre>
<span class="prompt">chaland ~ $</span> echo "$HOME/*"
/users/87/maths/doligez/*</pre>
<p>
Une technique utile: Quand on juxtapose deux cha<68>nes de caract<63>res quot<6F>es, le
shell les concat<61>ne, et elles ne forment qu'un argument. Exemple:
</p>
<pre>
<span class="prompt">chaland ~ $</span> echo "'"'"'
'"</pre>
<p>
Quant aux interactions plus compliqu<71>es (backslashes <20> l'int<6E>rieur des
guillemets, guillemets <20> l'int<6E>rieur des apostrophes, etc.), le meilleur moyen
de savoir si <20>a donne bien le r<>sultat attendu est d'essayer. La commande
<code>echo</code> est bien utile dans ce cas.
</p>
<h4>Les backquotes (<code>`</code>)</h4>
<p>
Derni<EFBFBD>re forme de quotation: <code>`<em>commande</em>`</code>. Le shell
ex<EFBFBD>cute la <em>commande</em> indiqu<71>e entre backquotes, lit la sortie de la
commande mot par mot, et remplace <code>`</code> <em>commande</em>
<code>`</code> par la liste de ces mots. Exemple<6C>:
</p>
<pre>
<span class="prompt">chaland ~ $</span> echo `ls`
Mail News bin foo lib misc mur notes.aux notes.dvi notes.log
notes.tex planar text
<span class="prompt">chaland ~ $</span> ls -l `which emacs`
-rwxr-xr-t 1 root taff 978944 Jul 16 1991 /usr/local/bin/emacs</pre>
<p>
La commande <code>which <em>cmd</em></code> employ<6F>e ci-dessus affiche sur sa
sortie le nom absolu du fichier ex<65>cut<75> par le shell quand on lance la
commande it <em>cmd</em><3E>:
</p>
<pre>
<span class="prompt">chaland ~ $</span> which emacs
/usr/local/bin/emacs</pre>
<h3><a name="redirections">Redirections</a></h3>
<p>
Chaque commande a une <em>entr<74>e standard</em>, une <em>sortie standard</em>,
et une <em>sortie d'erreur</em>. Par d<>faut, l'entr<74>e standard est le clavier,
la sortie standard est l'<27>cran, et la sortie d'erreur est aussi l'<27>cran.
</p>
<h4>Rediriger la sortie dans un fichier<65>: <code>&gt;</code></h4>
<p>
On peut <em> rediriger</em> la sortie standard d'une commande vers un fichier
(caract<63>re <code>&gt;</code>). Le r<>sultat de la commande sera plac<61> dans le
fichier au lieu de s'afficher sur l'<27>cran. Exemple:
</p>
<pre><span class="prompt">chaland ~ $</span> ls -l &gt; foo</pre>
<p>
Le r<>sultat de <code>ls -l</code> ne s'affiche pas <20> l'<27>cran, mais il est plac<61>
dans le fichier <code>foo</code>. On peut alors taper
</p>
<pre><span class="prompt">chaland ~ $</span> less foo</pre>
<p class="continue">
(ou <code>more foo</code>)
pour lire le fichier page par page.
</p>
<h4>Rediriger l'entr<74>e<EFBFBD>: <code>&lt;</code></h4>
<p>
On peut aussi rediriger l'entr<74>e standard d'une commande (caract<63>re
<code>&lt;</code>). La commande lira alors le fichier au lieu du clavier.
Exemple:
</p>
<pre><span class="prompt">chaland ~ $</span> elm leroy &lt; foo</pre>
<p class="continue">
envoie par mail <20> Xavier Leroy le r<>sultat de la commande <code>ls -l</code> de
tout <20> l'heure.
</p>
<p>
On peut aussi taper <code>more &lt; foo</code> qui est <20>quivalent <20>
<code>more foo</code> car <code>more</code> sans argument lit son entr<74>e
standard et l'affiche page par page sur le terminal.
</p>
<h4>Connecter la sortie d'une commande sur l'entr<74>e d'une autre<72>:
<code>|</code></h4>
<p>
On peut se passer du fichier interm<72>diaire gr<67>ce <20> un <em>pipe</em>
(caract<63>re <code>|</code>). Un pipe connecte directement la sortie standard d'une
commande sur l'entr<74>e standard d'une autre commande. Exemple: pour afficher
page par page la liste des fichiers du r<>pertoire courant, faire
</p>
<pre><span class="prompt">chaland ~ $</span> ls -l | less</pre>
<p>
Le pipe est d'un usage tr<74>s courant et rend beaucoup de services.
</p>
<h4>R<>capitulatif</h4>
<p>
La panoplie compl<70>te des redirections est la suivante (le tableau indique les
redirections qui diff<66>rent selon les shells)<29>:
</p>
<ul>
<li><code>&gt;</code><3E>: change la sortie standard de la commande pour la placer
dans un fichier.
</li>
<li><code>&lt;</code><3E>: change l'entr<74>e standard de la commande pour la prendre
dans un fichier.
</li>
<li><code>|</code><3E>: branche la sortie standard de la commande de gauche sur
l'entr<74>e standard de la commande de droite.
</li>
<li><code>&gt;&gt;</code><3E>: change la sortie standard pour l'ajouter <20> la fin
d'un fichier existant.
</li>
<li><code>||</code><3E>: ex<65>cuter la commande suivante si la premi<6D>re a
<EFBFBD>chou<EFBFBD>.
</li>
<li><code>&amp;&amp;</code><3E>: n'ex<65>cuter la commande suivante que si la
premi<EFBFBD>re a r<>ussi.
</li>
</ul>
<table class="tableau">
<tr>
<th> Fonction </th>
<th> Bourne shell </th>
<th> Z-shell </th>
</tr>
<tr>
<td>Redirige la sortie d'erreur (2) et la sortie standard (1) sur l'entr<74>e
de la commande suivante</td>
<td><code>2&gt;&amp;1 |</code></td>
<td><code> |&amp;</code></td>
</tr>
<tr>
<td>Redirige la sortie d'erreur et la sortie standard dans un fichier</td>
<td><code>2&gt;&amp;1 &gt;</code></td>
<td><code> &gt;&amp;</code></td>
</tr>
<tr>
<td>Redirige la sortie d'erreur et la sortie
standard <20> la fin d'un fichier existant</td>
<td><code>2&gt;&amp;1 &gt;&gt;</code></td>
<td><code>&gt;&gt;&amp;</code></td>
</tr>
</table>
<h4>Remarques</h4>
<p>
Normalement, une redirection avec <code>&gt;</code> sur un fichier qui
existe d<>j<EFBFBD> efface le contenu du fichier avant d'y placer le r<>sultat de la
commande. Les shells ont des options pour demander confirmation, ou
refuser d'effacer le fichier.
</p>
<p>
Une ligne de commandes contenant des <code>|</code> s'appelle un pipe-line.
Quelques commandes souvent utilis<69>es dans les pipe-lines sont:
</p>
<ul>
<li><a href="fichiers.html#less">more</a> (ou <code>less</code>,
bien plus <20>volu<6C>) <20> la fin du pipe-line, affiche le r<>sultat page par page,
pour laisser le temps de le lire.
</li>
<li><a href="divers.html#wc">wc</a> compte le nombre de
caract<EFBFBD>res, de mots et de lignes de son entr<74>e.
</li>
<li><a href="chercher.html#grep">grep</a> cherche dans son
entre les lignes contenant un mot donn<6E>, et les <20>crit sur sa sortie.
</li>
<li><a href="filtres.html#sort">sort</a> lit toutes les lignes
de son entr<74>e, les trie, et les <20>crit dans l'ordre sur sa sortie. Par d<>faut
l'ordre est alphab<61>tique.
</li>
<li><a href="fichiers.html#tail">tail</a> <20>crit sur sa sortie
les derni<6E>res lignes de son entr<74>e.
</li>
<li><a href="fichiers.html#head">head</a> <20>crit sur sa sortie
les premi<6D>res lignes de son entr<74>e.
</li>
<li><a href="fichiers.html#cat">cat</a> copie plusieurs fichiers
sur sa sortie.
</li>
<li><a href="filtres.html#fold">fold</a> coupe les lignes de son
entr<EFBFBD>e <20> 80 caract<63>res et <20>crit le r<>sultat sur sa sortie.
</li>
</ul>
<h4>Exemples</h4>
<pre>cat glop buz &gt; toto</pre>
<p>
Concat<EFBFBD>ne les fichiers <code>glop</code> et <code>buz</code> et place le
r<EFBFBD>sultat dans <code>toto</code>.
</p>
<pre>wc -w /usr/dict/words</pre>
<p>
Affiche le nombre de mots du dictionnaire Unix.
</p>
<pre>grep gag /usr/dict/words | tail</pre>
<p>
Affiche les 10 derniers mots du dictionnaire qui contiennent la cha<68>ne
<code>gag</code>.
</p>
<h3><a name="variables">Variables</a></h3>
<p>
Le shell a des variables. Pour d<>signer le contenu d'une variable, on <20>crit
le nom de la variable pr<70>c<EFBFBD>d<EFBFBD> d'un dollar. Exemple: <code>echo $HOME</code>
affiche le nom du r<>pertoire personnel de l'utilisateur.
</p>
<p>
La fa<66>on de donner une valeur <20> une variable varie selon le type de shell
utilis<EFBFBD><EFBFBD>:
</p>
<p>
<strong>C-Shell</strong> (<code>csh</code>, <code>tcsh</code>,
<code>lcsh</code>)<29>: on utilise la commande <code>setenv</code><3E>:
</p>
<pre>
<span class="prompt">chaland ~ $</span> setenv foo bar
<span class="prompt">chaland ~ $</span> echo $foo
bar</pre>
<p>
Famille des <strong>Bourne Shell</strong> (<code>sh</code>, <code>bash</code>,
<code>zsh</code>, <code>ksh</code>)<29>: on utilise <code>export</code><3E>:
</p>
<pre>
<span class="prompt">chaland ~ $</span> foo=bar
<span class="prompt">chaland ~ $</span> export foo
<span class="prompt">chaland ~ $</span> echo $foo
bar</pre>
<p>
Les valeurs des variables sont accessibles aux commandes lanc<6E>es par le shell.
L'ensemble de ces valeurs constitue l'<em>environnement</em>. On peut aussi
supprimer une variable de l'environnement avec <code>unsetenv</code>
(C-Shell) ou <code>unset</code> (Bourne Shell).
</p>
<p>
Quelques variables d'environnement:
</p>
<ul>
<li><code>DISPLAY</code><3E>: L'<27>cran sur lequel les programmes X travaillent.
C'est souvent de la forme<6D>: <code>machine.somehost.somewhere:0.0</code>
Si c'est vide, c'est qu'il n'y a pas d'affichage graphique possible.
</li>
<li><code>PRINTER</code><3E>: pour les commandes d'impression. Contient le nom de
l'imprimante sur laquelle il faut envoyer vos fichiers.
</li>
<li><code>EDITOR</code><3E>: utilis<69>e par <code>mutt</code>, <code>forum</code>,
et beaucoup d'autres commandes. Contient le nom de votre <20>diteur de textes
pr<EFBFBD>f<EFBFBD>r<EFBFBD>.
</li>
<li><code>VISUAL</code><3E>: la m<>me chose qu'<code>EDITOR</code>.
</li>
<li><code>SHELL</code><3E>: contient le nom de votre shell.
</li>
<li><code>HOME</code><3E>: contient le nom de votre r<>pertoire personnel.
</li>
<li><code>USER</code><3E>: contient votre nom de login.
</li>
<li><code>LOGNAME</code><3E>: la m<>me chose que <code>USER</code>.
</li>
<li><code>PATH</code><3E>: contient une liste de r<>pertoires dans lesquels le
shell va chercher les commandes.
</li>
</ul>
<p>
Exercice<EFBFBD>: Assurez-vous que <code>/usr/local/games/bin</code> se trouve
bien dans votre PATH.
</p>
<h2><a name="programmation">Programmation du shell <code>sh</code></a></h2>
<p>
Un shell, quel qu'il soit, peut ex<65>cuter des commandes prises dans un
fichier. Un fichier contenant des commandes pour le shell est appel<65> un
<em>script</em>. C'est en fait un <em>programme</em> <20>crit <em>dans le
langage du shell</em>. Ce langage comprend non seulement les commandes que
nous avons d<>j<EFBFBD> vues, mais aussi des structures de contr<74>le
(constructions conditionnelles et boucles).
</p>
<p>
Pour la programmation du shell, nous allons utiliser le shell <code>sh</code>,
qui est le plus r<>pandu et standard. Ce que nous avons vu jusqu'ici
s'applique aussi bien <20> <code>sh</code> qu'<27> <code>zsh</code> et aussi <20>
<code>csh</code>, <20> l'exception de <code>setenv</code> et de certaines
redirections signal<61>es. Pour <20>tre un script, un fichier doit commencer par
la ligne:
</p>
<pre>#!/bin/sh</pre>
<p>
Il doit aussi avoir <20>tre ex<65>cutable (bit <code>x</code>). Le
<code>#!/bin/sh</code> sur la premi<6D>re ligne indique que ce script doit <20>tre
ex<EFBFBD>cut<EFBFBD> par le shell <code>sh</code> dont on indique le chemin d'acc<63>s.
</p>
<h3><a name="structures">Structures de contr<74>le</a></h3>
<h4>for</h4>
2002-11-23 17:19:08 +01:00
<pre>for <em>var</em> in <em>liste de cha<68>nes</em> ;
do <em>commandes</em> ; done</pre>
2002-11-23 16:58:15 +01:00
<p>
Affecte successivement <20> la variable de nom <em>var</em> chaque cha<68>ne de
caract<EFBFBD>res trouv<75>e dans la <em>liste de cha<68>nes</em>, et ex<65>cute les
<em>commandes</em> une fois pour chaque cha<68>ne.
</p>
<p>
Rappel<EFBFBD>: <code>$<em>var</em></code> acc<63>de <20> la valeur courante de
<em>var</em>. La partie <em>commandes</em> est une suite de commandes,
s<EFBFBD>par<EFBFBD>es par des <code>;</code> ou des retours <20> la ligne. (Tous les
<code>;</code> dans cette syntaxe peuvent aussi <20>tre remplac<61>s par des
retours <20> la ligne.)
</p>
<p>
Exemple<EFBFBD>:
</p>
<pre>for i in *; do echo $i; done</pre>
<p class="continue">
affiche les noms de tous les fichiers du r<>pertoire courant, un par ligne.
</p>
<h4>if</h4>
<pre>if <em>commande</em> ; then <em>commandes</em> ;
else <em>commandes</em> ; fi</pre>
<p>
Ex<EFBFBD>cute l'une ou l'autre des listes de <em>commandes</em>, suivant que la
premi<EFBFBD>re <em>commande</em> a r<>ussi ou non (voir ci-dessous).
</p>
<h4>while</h4>
<pre>while <em>commande</em> ; do <em>commande</em> ; done</pre>
<p>
Ex<EFBFBD>cute les <em>commandes</em> de mani<6E>re r<>p<EFBFBD>t<EFBFBD>e tant que la premi<6D>re
<em>commande</em> r<>ussit.
</p>
<h4>case</h4>
<pre>case <em>cha<68>ne</em> in
<em>pattern</em>) <em>commande</em> ;;
<em>pattern</em>) <em>commande</em> ;;
esac</pre>
<p>
Ex<EFBFBD>cute la premi<6D>re <em>commande</em> telle que la <em>cha<68>ne</em> est de la
forme <em>pattern</em>. Un <em>pattern</em> est un mot contenant
<EFBFBD>ventuellement les constructions <code>*</code>, <code>?</code>,
<code>[a-d]</code>, avec la m<>me signification que pour les raccourcis dans
les noms de fichiers. Exemple<6C>:
</p>
<pre>
case $var in
[0-9]*) echo 'Nombre';;
[a-zA-Z]*) echo 'Mot';;
*) echo 'Autre chose';;
esac</pre>
<h3><a name="retour">Code de retour</a></h3>
<p>
On remarque que la condition des commandes <code>if</code> et
<code>while</code> est une commande. Chaque commande renvoie un code de
retour (qui est ignor<6F> en utilisation normale). Si le code est 0, la
commande a r<>ussi; sinon, la commande a <20>chou<6F>. Par exemple, le compilateur
<code>cc</code> renvoie un code d'erreur non nul si le fichier compil<69>
contient des erreurs, ou s'il n'existe pas.
</p>
<p>
Les commandes <code>if</code> et <code>while</code> consid<69>rent donc le code
de retour 0 comme <20><>vrai<61><69>, et tout autre code comme <20><>faux<75><78>.
</p>
<p>
Il existe une commande <code>test</code>, qui <20>value des expressions bool<6F>ennes
pass<EFBFBD>es en argument, et renvoie un code de retour en fonction du r<>sultat.
Elle est bien utile pour les scripts. Exemple<6C>:
</p>
<pre>
if test $var = foo
then echo 'La variable vaut foo'
else echo 'La variable ne vaut pas foo'
fi</pre>
<h3><a name="shvariables">Variables</a></h3>
<p>
Dans les scripts, on peut utiliser des variables d<>finies <20> l'ext<78>rieur
(avec <code>setenv</code> ou <code>export</code>), mais aussi d<>finir ses
variables locales propres au script. On donne une valeur <20> une variable avec
une commande de la forme
<code><em>nom-de-variable</em>=<em>valeur</em></code>. Les variables sont
utilis<EFBFBD>es pour stocker des informations.
</p>
<p>
On a aussi des variables sp<73>ciales, initialis<69>es automatiquement au
d<EFBFBD>but du script:
</p>
<table class="tableau">
<tr>
<td><code>$0</code></td>
<td>Le nom de la commande (i.e.<2E>: du script)</td>
</tr>
<tr>
<td><code>$1</code>, <code>$2</code>, etc.</td>
<td>Le premier, deuxi<78>me, etc, argument pass<73>s au script.</td>
</tr>
<tr>
<td><code>$*</code></td>
<td>La liste de tous les arguments pass<73>s au script.</td>
</tr>
<tr>
<td><code>$#</code></td>
<td>Le nombre d'arguments pass<73>s au script.</td>
</tr>
<tr>
<td><code>$?</code></td>
<td>Le code de retour de la derni<6E>re commande lanc<6E>e.</td>
</tr>
<tr>
<td><code>$!</code> </td>
<td>Le num<75>ro de process de la derni<6E>re commande lanc<6E>e en t<>che de fond.</td>
</tr>
<tr>
<td><code>$$</code></td>
<td>Le num<75>ro de process du shell lui-m<>me.</td>
</tr>
</table>
<div class="metainformation">
Bas<EFBFBD> sur un polycopi<70> de Roberto Di Cosmo, Xavier Leroy et Damien Doligez.
Ajustements<EFBFBD>: Nicolas George.
Derni<EFBFBD>re modification le 2002-11-16.
</div>
</body>
</html>