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>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Le mot <em>shell</em> signifie <20> coquille <3B> en anglais. Il
|
|
|
|
|
s'agit du programme que vous utilisez r<>guli<6C>rement <20> l'ENS, et qui
|
|
|
|
|
interpr<EFBFBD>te les commandes. Par exemple, vous y tapez <code>pine</code> ou
|
|
|
|
|
<code>mutt</code>, <code>forum</code>, <code>cc</code>,
|
|
|
|
|
<code>mozilla</code>, etc.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
|
|
|
|
Mais quel rapport avec une coquille ? Eh bien, dans une coquille
|
|
|
|
|
vous pouvez mettre de l'eau, pour la porter ensuite <20> votre
|
|
|
|
|
bouche ; vous pouvez y mettre du sable avant de le verser dans des
|
|
|
|
|
bocaux ; en somme, une coquille est un r<>cipient qui permet
|
|
|
|
|
de manipuler toutes sortes de contenus. Il en va de m<>me du shell. C'est
|
|
|
|
|
un outil en mode texte qui permet l'exploitation d'un grand nombre de
|
|
|
|
|
ressources de l'ordinateur.
|
|
|
|
|
</p>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
|
|
|
|
Cette page vous donnera les rudiments pour exploiter les deux
|
|
|
|
|
principales fonctionnalit<69>s du shell :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
<li> l'usage interactif, reposant sur les <strong>lignes de
|
|
|
|
|
commandes</strong> ;</li>
|
|
|
|
|
<li> la conception de <strong>scripts</strong> (programmes <20>crits en
|
|
|
|
|
shell). </li>
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3><a name="etats">Les deux <20>tats du shell</a>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</h3>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
|
|
|
|
Le shell, comme le normalien, ne conna<6E>t que deux <20>tats :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
<li> le travail ;</li>
|
|
|
|
|
<li> l'inactivit<69>.</li>
|
|
|
|
|
</ul>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Le shell, une fois lanc<6E>, est inactif : il attend qu'on lui donne
|
|
|
|
|
des ordres. Quand on lui en donne un, il l'ex<65>cute ; et quand il a
|
|
|
|
|
termin<EFBFBD>, il retourne <20> son <20>tat d'inactivit<69>, en attente d'un nouveau
|
|
|
|
|
commandement.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Quand le shell est inactif, il affiche une <em>invite</em>
|
|
|
|
|
(<em>prompt</em> en anglais), qui ressemble <20> cela :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<pre><span class="prompt">chaland ~ $</span></pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Un curseur, parfois clignotant, indique que le shell attend que vous lui
|
|
|
|
|
tapiez des instructions.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h3><a name="path">Comment le shell trouve-t-il les commandes<65>?</a>
|
|
|
|
|
</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
J'ai l'habitude de taper des commandes dans le shell, et je vois qu'il
|
|
|
|
|
r<EFBFBD>agit. Mais comment comprend-il ce que je veux faire ?
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Prenons un cas simple. Je tape la commande <code>bonjour</code> <20>
|
|
|
|
|
l'invite (<em>prompt</em>) du shell. Il va chercher <20> plusieurs endroits
|
|
|
|
|
ce que j'entends par l<> :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ol>
|
|
|
|
|
<li> d'abord, il va se demander si <code>bonjour</code> n'est pas une de
|
|
|
|
|
ses commandes int<6E>gr<67>es ; si c'est le cas, il l'ex<65>cute
|
|
|
|
|
directement, sinon il passe <20> l'<27>tape suivante ;</li>
|
|
|
|
|
<li> ensuite, il va lire le contenu d'une variable, qui s'appelle
|
|
|
|
|
<code>PATH</code>, et qui indique le <20> chemin <3B> o<> trouver les
|
|
|
|
|
commandes que l'on appelle. Par exemple, si la variable PATH contient
|
|
|
|
|
les r<>pertoires :
|
|
|
|
|
<ul>
|
|
|
|
|
<li> <code>/usr/bin</code> </li>
|
|
|
|
|
<li> <code>/bin</code> et </li>
|
|
|
|
|
<li> <code>/home/toto/bin</code>,</li>
|
|
|
|
|
</ul>
|
|
|
|
|
alors le shell va chercher successivement les commandes :
|
|
|
|
|
<ul>
|
|
|
|
|
<li> <code>/usr/bin/bonjour</code>,</li>
|
|
|
|
|
<li> <code>/bin/bonjour</code> et </li>
|
|
|
|
|
<li> <code>/home/toto/bin/bonjour</code> ;</li>
|
|
|
|
|
</ul></li>
|
|
|
|
|
<li> enfin, s'il ne trouve la commande dans aucun des r<>pertoires
|
|
|
|
|
r<EFBFBD>f<EFBFBD>renc<EFBFBD>s par le <code>PATH</code>, il va renvoyer un message d'erreur
|
|
|
|
|
en disant que d<>sol<6F>, il ne voit pas ce que l'on entend par
|
|
|
|
|
<code>bonjour</code>. Exemple :
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<pre>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<span class="prompt">chaland ~ $</span> bonjour
|
|
|
|
|
bonjour: Command not found</pre> </li>
|
|
|
|
|
</ol>
|
|
|
|
|
|
|
|
|
|
<p> La <a href="#variables">variable</a> <code>PATH</code> consiste en
|
|
|
|
|
une liste de r<>pertoires s<>par<61>s par des
|
|
|
|
|
<EFBFBD> <code>:</code> <3B>. Si vous voulez voir <20> quoi ressemble votre
|
|
|
|
|
PATH, tapez :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">chaland ~ $</span> echo $PATH</pre>
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3><a name="builtins">Commandes internes</a></h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Certaines commandes du shell ne sont pas des programmes mais des
|
|
|
|
|
commandes <em>internes</em> (<em>builtins functions</em>). Comme nous
|
|
|
|
|
l'avons vu, elles sont directement reconnues et ex<65>cut<75>es par le shell.
|
|
|
|
|
Un exemple de commande interne est <code>cd</code> ; elle modifie
|
|
|
|
|
le r<>pertoire courant du shell.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<div class="attention">
|
|
|
|
|
<p>
|
|
|
|
|
Attention : si vous cr<63>ez un script (c'est-<2D>-dire un programme
|
|
|
|
|
<EFBFBD>crit en langage shell) qui utilise <code>cd</code>, il ne modifie pas
|
|
|
|
|
le r<>pertoire courant du shell qui lance ce script, mais celui d'un
|
|
|
|
|
shell qui est cr<63><72> <20> l'occasion de l'ex<65>cution de ce script, et qui
|
|
|
|
|
meurt <20> la fin de cette ex<65>cution.</p>
|
|
|
|
|
|
|
|
|
|
<p> Exemple : je cr<63>e un script <code>aller</code> qui contient les
|
|
|
|
|
lignes suivantes : </p>
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<pre>
|
|
|
|
|
#! /bin/sh
|
|
|
|
|
cd $*</pre>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
|
|
|
|
Nous aurons alors :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">chaland ~ $</span> aller toto
|
|
|
|
|
<span class="prompt">chaland ~ $</span> cd toto
|
|
|
|
|
<span class="prompt">chaland ~/toto $</span></pre>
|
|
|
|
|
|
|
|
|
|
</div>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
|
|
|
|
|
<h3><a name="prog">Quels programmes utilisent le langage du shell<6C>?</a></h3>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
La r<>p<EFBFBD>tition de commandes complexes en ligne de commande du shell est
|
|
|
|
|
rapidement fastidieuse ; aussi est-il tr<74>s pratique de conna<6E>tre
|
|
|
|
|
les bases de la programmation de scripts shell. Les scripts servent <20>
|
|
|
|
|
automatiser ou syst<73>matiser des t<>ches.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</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>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p> Il existe encore le script <code>.xinitrc</code>, qui lance X ;
|
|
|
|
|
X est le gestionnaire de fen<65>tres classique sous Unix.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Le nombre de scripts possibles est illimit<69> ; vous pouvez en cr<63>er
|
|
|
|
|
autant que vous voulez, selon vos besoins : c'est ainsi que l'on
|
|
|
|
|
personnalise son syst<73>me et qu'on l'adapte <20> ses exigences, plut<75>t que
|
|
|
|
|
l'inverse.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<h2><a name="ligne">La ligne de commande</a></h2>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h3><a name="raccourcis">Raccourcis pour les noms de fichiers : les
|
|
|
|
|
jokers</a></h3>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h4>L'<27>toile : *</h4>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<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
|
2005-05-28 13:05:39 +02:00
|
|
|
|
point). Exemple :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</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>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h4>Le point d'interrogation : ?</h4>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<p>
|
2002-12-20 22:33:07 +01:00
|
|
|
|
On a aussi le <strong>point d'interrogation</strong> <code>?</code>, qui
|
2002-11-23 16:58:15 +01:00
|
|
|
|
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>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h4>Les crochets : []</h4>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<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>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Exemples :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</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
|
2005-05-28 13:05:39 +02:00
|
|
|
|
(simples quotes) <code>'</code>. Tout ce qui se trouve entre deux
|
|
|
|
|
apostrophes sera pass<73> tel quel par le shell <20> la
|
|
|
|
|
commande. Exemple :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">chaland ~ $</span> echo '$?*'
|
|
|
|
|
$?*</pre>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h4>Les guillemets doubles ou doubles quotes (<code>"</code>)</h4>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
Les guillemets se comportent comme les apostrophes, <20> une exception pr<70>s: les
|
2005-05-28 13:05:39 +02:00
|
|
|
|
dollars et les backslashes sont interpr<70>t<EFBFBD>s entre les guillemets.
|
|
|
|
|
Exemple :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">chaland ~ $</span> echo "$HOME/*"
|
|
|
|
|
/users/87/maths/doligez/*</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Une technique utile: Quand on juxtapose deux cha<68>nes de caract<63>res
|
|
|
|
|
quot<EFBFBD>es, le shell les concat<61>ne, et elles ne forment qu'un argument.
|
|
|
|
|
Exemple :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</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>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<code>`</code> par la liste de ces mots. Exemple :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</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>
|
|
|
|
|
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h3><a name="redirections">Entr<74>e, sortie et redirection</a></h3>
|
|
|
|
|
|
|
|
|
|
<h4>Entr<74>e et sortie</h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Un programme consiste <20> traiter des donn<6E>es, et <20> renvoyer des donn<6E>es
|
|
|
|
|
transform<EFBFBD>es : il transforme des informations, et c'est pourquoi
|
|
|
|
|
l'on parle d'<em>informatique</em>.</p>
|
|
|
|
|
|
|
|
|
|
<p> Prenons le programme <code>hachoir</code>, par exemple : on y
|
|
|
|
|
fait entrer des choses, elles sortent sous une autre forme, et dans
|
|
|
|
|
l'intervalle, elles subissent des transformations r<>guli<6C>res. Par
|
|
|
|
|
exemple, on fait entrer une vache, il en ressort du steak hach<63> ;
|
|
|
|
|
on y fait entrer des carottes, il en ressort des carottes rap<61>es.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Deux concepts permettent de mod<6F>liser cette transformation
|
|
|
|
|
d'informations : les concepts d'entr<74>e et de
|
|
|
|
|
sortie. L'<strong>entr<74>e</strong>, c'est la vache ou les carottes ;
|
|
|
|
|
la <strong>sortie</strong>, c'est le steak hach<63> ou les carottes
|
|
|
|
|
rap<EFBFBD>es.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h4>Sortie standard et sortie d'erreur</h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Mais cette premi<6D>re distinction entre entr<74>e et sortie ne suffit pas,
|
|
|
|
|
car la sortie d'un programme, c'est-<2D>-dire les messages qu'il renvoie,
|
|
|
|
|
sont de deux ordres : il y a les <em>messages normaux</em> relevant
|
|
|
|
|
de la transformation d'informations (par exemple le steak hach<63> ou les
|
|
|
|
|
carottes rap<61>es), mais il y a aussi des <em>messages d'erreur</em>.</p>
|
|
|
|
|
|
|
|
|
|
<p> Par exemple, si vous mettez, sur le tapis roulant qui m<>ne au
|
|
|
|
|
hachoir, un objet trop gros pour y rentrer, le hachoir, s'il est bien
|
|
|
|
|
con<EFBFBD>u, devra vous pr<70>venir qu'il n'arrive pas <20> hacher un objet si
|
|
|
|
|
gros. Et ce message, quoiqu'il sorte aussi bien du hachoir que le steak
|
|
|
|
|
hach<EFBFBD>, ne doit pas <20>tre trait<69> de la m<>me fa<66>on <20> sa sortie, et n'est
|
|
|
|
|
pas suivi des m<>mes cons<6E>quences. C'est pourquoi l'on distingue la
|
|
|
|
|
<strong>sortie standard</strong> et la <strong>sortie d'erreur</strong>.
|
|
|
|
|
</p>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Pour r<>sumer, chaque commande a donc :</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li> une <em>entr<74>e standard</em>, </li>
|
|
|
|
|
<li> une <em>sortie standard</em> et </li>
|
|
|
|
|
<li> une <em>sortie d'erreur</em>.</li>
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h4>Comportement par d<>faut</h4>
|
|
|
|
|
|
|
|
|
|
<p> 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>
|
|
|
|
|
|
|
|
|
|
<p> C'est sur le clavier que vous tapez ; ce que vous tapez et ce
|
|
|
|
|
que renvoient les programmes s'inscrit <20> l'<27>cran ; les messages
|
|
|
|
|
d'erreur renvoy<6F>s par les programmes s'affichent <20> l'<27>cran.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h4>Les redirections</h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Mais il ne s'agit l<> que du comportement par d<>faut, et pas d'un
|
|
|
|
|
comportement obligatoire. Vous pouvez tout <20> fait orienter diff<66>remment
|
|
|
|
|
vos programmes.</p>
|
|
|
|
|
|
|
|
|
|
<p> Par exemple, si vous donnez une vache comme entr<74>e au hachoir, vous
|
|
|
|
|
pouvez orienter la sortie vers une imprimante (au lieu de l'<27>cran,
|
|
|
|
|
propos<EFBFBD> par d<>faut), et vous imprimerez ainsi du steak hach<63>. </p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Ou encore, vous pouvez donner un plant de carottes comme entr<74>e au
|
|
|
|
|
programme <code>cueillette</code>, et envoyer la sortie (c'est-<2D>-dire
|
|
|
|
|
les carottes cueillies) au programme <code>hachoir</code>.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<h4>Rediriger la sortie dans un fichier<65>: <code>></code></h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
On peut <em> rediriger</em> la sortie standard d'une commande vers un
|
|
|
|
|
fichier (caract<63>re <20> <code>></code> <3B>). Le r<>sultat de la
|
|
|
|
|
commande sera plac<61> dans le fichier au lieu de s'afficher sur l'<27>cran.
|
|
|
|
|
Exemple :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre><span class="prompt">chaland ~ $</span> ls -l > 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>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
|
|
|
|
|
<h4>Ajouter la sortie <20> un fichier<65>: <code>>></code></h4>
|
|
|
|
|
|
|
|
|
|
<p> On veut parfois ajouter la sortie d'un programme <20> un fichier, sans
|
|
|
|
|
effacer ce qui pr<70>c<EFBFBD>de. Or, par d<>faut, si l'on tape plusieurs fois
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre><span class="prompt">chaland ~ $</span> ls -l > foo</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">
|
|
|
|
|
<EFBFBD> chaque fois, le contenu ant<6E>rieur du fichier <code>foo</code> est
|
|
|
|
|
<EFBFBD>cras<EFBFBD> par le contenu ult<6C>rieur.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Pour <20>viter cela, il existe l'outil de redirection >>. Ainsi, si
|
|
|
|
|
vous tapez plusieurs fois
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre><span class="prompt">chaland ~ $</span> ls -l >> foo</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">
|
|
|
|
|
le fichier <code>foo</code> contiendra <em><3E> la suite</em> tout ce que
|
|
|
|
|
vous a renvoy<6F> la commande.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<h4>Rediriger l'entr<74>e<EFBFBD>: <code><</code></h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
On peut aussi rediriger l'entr<74>e standard d'une commande (caract<63>re
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<EFBFBD> <code><</code> <3B>). La commande lira alors le fichier au
|
|
|
|
|
lieu du clavier. Exemple :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre><span class="prompt">chaland ~ $</span> elm leroy < 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 < 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>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Il devient rapidement ennuyeux de taper :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre><span class="prompt">chaland ~ $</span> ls -l > foo
|
|
|
|
|
<span class="prompt">chaland ~ $</span> less < foo
|
|
|
|
|
<span class="prompt">chaland ~ $</span> rm foo</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
On peut se passer du fichier interm<72>diaire (<code>foo</code> dans notre
|
|
|
|
|
exemple) gr<67>ce <20> un <em>pipe</em> (caract<63>re
|
|
|
|
|
<EFBFBD> <code>|</code> <3B>). 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<EFBFBD>pertoire courant, faire
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre><span class="prompt">chaland ~ $</span> ls -l | less</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Le pipe, ou tube, est d'un usage tr<74>s courant, et rend beaucoup de
|
|
|
|
|
services.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Succ<63>s et erreur</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
On a parfois besoin de savoir si une commande a r<>ussi ou non avant d'en
|
|
|
|
|
lancer une autre. Les indicateurs <code>&&</code> et
|
|
|
|
|
<code>||</code> permettent, respectivement, de lancer une commande si
|
|
|
|
|
(et seulement si) la pr<70>c<EFBFBD>dente a r<>ussi ou <20>chou<6F>.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Par exemple, si j'ai un fichier <code>foo</code>, j'obtiens :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">chaland ~ $</span> ls foo && echo "J'ai un fichier foo."
|
|
|
|
|
foo
|
|
|
|
|
J'ai un fichier foo.
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Si je n'ai pas de fichier <code>foo</code>, le message ne s'affiche
|
|
|
|
|
pas. En revanche, si je tape alors :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">chaland ~ $</span> ls foo || echo "Je n'ai pas de fichier foo."
|
|
|
|
|
ls: foo: No such file or directory
|
|
|
|
|
Je n'ai pas de fichier foo.
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>R<>capitulatif</h3>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<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>></code><3E>: change la sortie standard de la commande pour la placer
|
|
|
|
|
dans un fichier.
|
|
|
|
|
</li>
|
|
|
|
|
<li><code><</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>>></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>&&</code><3E>: n'ex<65>cuter la commande suivante que si la
|
|
|
|
|
premi<EFBFBD>re a r<>ussi.
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h3>Redirection des sorties standard et d'erreur</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Il est parfois utile de rediriger la sortie standard et la sortie
|
|
|
|
|
d'erreur vers un m<>me endroit. Pour cela, on utilise le motif
|
|
|
|
|
<code>2>&1</code> avant la redirection.
|
|
|
|
|
</p>
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<table class="tableau">
|
|
|
|
|
<tr>
|
|
|
|
|
<th> Fonction </th>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<th> Bourne shell (sh, bash) </th>
|
|
|
|
|
<th> Z-shell (zsh) </th>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</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>&1 |</code></td>
|
|
|
|
|
<td><code> |&</code></td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td>Redirige la sortie d'erreur et la sortie standard dans un fichier</td>
|
|
|
|
|
<td><code>2>&1 ></code></td>
|
|
|
|
|
<td><code> >&</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>&1 >></code></td>
|
|
|
|
|
<td><code>>>&</code></td>
|
|
|
|
|
</tr>
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
<h4>Remarques</h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Normalement, une redirection avec <code>></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>
|
2002-12-16 23:26:43 +01:00
|
|
|
|
<li><a href="&url.tuteurs;unix/exercices/enchainer.html#syst">sort</a> lit toutes les lignes
|
2002-11-23 16:58:15 +01:00
|
|
|
|
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>
|
2002-12-15 19:57:30 +01:00
|
|
|
|
<li><a href="fichiers.html#head">tail</a> <20>crit sur sa sortie
|
2002-11-23 16:58:15 +01:00
|
|
|
|
les derni<6E>res lignes de son entr<74>e.
|
|
|
|
|
</li>
|
2002-12-15 19:57:30 +01:00
|
|
|
|
<li><a href="fichiers.html#head">head</a> <20>crit sur sa sortie
|
2002-11-23 16:58:15 +01:00
|
|
|
|
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>
|
2002-12-16 23:26:43 +01:00
|
|
|
|
<li><code>fold</code> coupe les lignes de son
|
2002-11-23 16:58:15 +01:00
|
|
|
|
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 > 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>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h4>Qu'est-ce qu'une variable ?</h4>
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Une variable est l'assignation d'une <20>tiquette <20> un contenu ; ce
|
|
|
|
|
contenu, comme l'indique le mot <20> variable <3B>, peut changer
|
|
|
|
|
autant que l'on veut ; l'assignation de l'<27>tiquette <20> ce contenu,
|
|
|
|
|
elle, est fixe, aussi longtemps que l'on ne dissout pas la
|
|
|
|
|
variable. </p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
La notion de variable est commune <20> presque tous les langages
|
|
|
|
|
informatiques, et en particulier aux langages de programmation. Ceux qui
|
|
|
|
|
ont d<>j<EFBFBD> manipul<75> des langages sont donc familiers avec cette
|
|
|
|
|
notion. Pour les autres, un petit exemple les aidera peut-<2D>tre <20> la
|
|
|
|
|
saisir.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
|
|
|
|
Mettons que vous programmiez le hachoir dont nous parlions plus haut. Un
|
|
|
|
|
hachoir est un instrument dangereux, <20> ne pas mettre <20> la port<72>e des
|
|
|
|
|
enfants. Robert le jardinier, qui a con<6F>u ce hachoir, veut <20>tre le seul
|
|
|
|
|
<EFBFBD> pouvoir l'utiliser, sans quoi le petit <20>mile pourrait se blesser en y
|
|
|
|
|
mettant le doigt.</p>
|
|
|
|
|
|
|
|
|
|
<p> Ainsi, il va dire au programme <code>hachoir</code> de v<>rifier la
|
|
|
|
|
variable <code>USER</code>, qui contient le nom de l'utilisateur. Si le
|
|
|
|
|
nom <20> Robert <3B> est associ<63> <20> l'<27>tiquette <code>USER</code>,
|
|
|
|
|
alors le programme se met en route ; sinon, il dit <20> l'utilisateur
|
|
|
|
|
de ne pas utiliser cet instrument sans la pr<70>sence d'un adulte, et de
|
|
|
|
|
bien regarder des deux c<>t<EFBFBD>s avant de traverser la rue.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Certaines variables sont pr<70>d<EFBFBD>finies, par exemple
|
|
|
|
|
<code>USER</code> ; mais on peut en cr<63>er autant que l'on veut. Par
|
|
|
|
|
exemple, si Robert veut autoriser d'autres adultes que lui <20> utiliser
|
|
|
|
|
son hachoir, il peut faire que le programme demande <20> l'utilisateur quel
|
|
|
|
|
<EFBFBD>ge il a ; la r<>ponse est enregistr<74>e dans la variable
|
|
|
|
|
<code>age</code> ; ensuite, le programme va examiner le contenu de
|
|
|
|
|
cette variable. Si <code>age >= 18</code>, alors le hachoir peut se
|
|
|
|
|
mettre en route ; mais si <code>age < 18</code>, le hachoir
|
|
|
|
|
refuse de se mettre en marche.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h4>Les variables en shell</h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
En shell, pour d<>signer le contenu d'une variable, on <20>crit le nom de la
|
|
|
|
|
variable pr<70>c<EFBFBD>d<EFBFBD> du signe dollar. Exemple : <code>echo
|
|
|
|
|
$HOME</code> affiche le nom du r<>pertoire personnel de l'utilisateur,
|
|
|
|
|
m<EFBFBD>moris<EFBFBD> par la variable <code>HOME</code>.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h5>Les noms de variables</h5>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Par convention, les variables relevant du syst<73>me, comme
|
|
|
|
|
<code>HOME</code>, <code>USER</code> et beaucoup d'autres, sont en
|
|
|
|
|
majuscules, tandis que l'on recommande d'<27>crire en minuscules les
|
|
|
|
|
variables que l'on se cr<63>e soi-m<>me. On <20>vite ainsi la d<>sagr<67>able
|
|
|
|
|
surprise de remplacer une variable importante et de casser tout ou
|
|
|
|
|
partie de son syst<73>me.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Les noms de variables sont en effet sensibles <20> la casse :
|
|
|
|
|
<code>USER</code>, <code>user</code>, <code>User</code>,
|
|
|
|
|
<code>uSeR</code> etc. sont des variables diff<66>rentes.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h5>D<>finir une variable</h5>
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<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>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
|
|
|
|
|
<h5>Les variables d'environnement</h5>
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
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).
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Quelques variables d'environnement:
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ul>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<li><code>DISPLAY</code><3E>: L'<27>cran sur lequel les programmes X
|
|
|
|
|
travaillent. Cette variable est souvent de la forme :
|
|
|
|
|
<code>machine.somehost.somewhere:0.0</code> Si cette variable 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<70>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>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
<li><code>HOME</code><3E>: contient le nom de votre r<>pertoire personnel.
|
2005-05-28 13:05:39 +02:00
|
|
|
|
</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>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</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>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
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. </p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Rendre un script ex<65>cutable</h3>
|
|
|
|
|
|
|
|
|
|
<p> Pour <20>tre un script, un fichier doit commencer par la ligne: </p>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<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
|
2005-05-28 13:05:39 +02:00
|
|
|
|
ex<EFBFBD>cut<EFBFBD> par le shell <code>sh</code> dont on indique le chemin
|
|
|
|
|
d'acc<63>s. Pour rendre un fichier ex<65>cutable, tapez :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<pre><span class="prompt">chaland ~</span> chmod u+x fichier
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">
|
|
|
|
|
(pour en savoir plus sur les droits attach<63>s <20> un fichier, consultez la
|
|
|
|
|
page sur <a href="droits.html">les droits d'acc<63>s</a>).
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<h3><a name="structures">Structures de contr<74>le</a></h3>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
|
|
|
|
C'est avec les structures de contr<74>le qu'un programme peut commencer <20>
|
|
|
|
|
devenir s<>rieux. Le principe g<>n<EFBFBD>ral de ces structures est le
|
|
|
|
|
suivant : adapter le comportement du programme selon les r<>ponses
|
|
|
|
|
apport<EFBFBD>es <20> certaines questions.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Nous avons d<>j<EFBFBD> vu une application possible des structures de contr<74>le
|
|
|
|
|
en parlant des variables. Le programme <code>hachoir</code> con<6F>u par
|
|
|
|
|
Robert le jardinier pose la question suivante : est-ce que
|
|
|
|
|
<code>$USER</code> vaut <20> Robert <3B> ?
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
<li> si oui, alors le hachoir doit se mettre en marche ;</li>
|
|
|
|
|
<li> si non, alors le hachoir doit refuser de se mettre en
|
|
|
|
|
marche.</li>
|
|
|
|
|
</ul>
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<h4>La boucle <code>if</code></h4>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
|
|
|
|
La structure de contr<74>le <code>if</code> est la plus courante de toutes,
|
|
|
|
|
et la plus <20>l<EFBFBD>mentaire. Elle est constitu<74>e de quatre termes :</p>
|
|
|
|
|
|
|
|
|
|
<ol>
|
|
|
|
|
<li> <code>if</code> (si), qui marque la condition <20> remplir ;
|
|
|
|
|
</li>
|
|
|
|
|
<li> <code>then</code> (alors), qui marque les cons<6E>quences si la
|
|
|
|
|
condition est remplie ; </li>
|
|
|
|
|
<li> <code>else</code> (sinon), qui est facultatif et marque le
|
|
|
|
|
comportement <20> adopter si la condition n'est pas remplie ; </li>
|
|
|
|
|
<li> <code>fi</code> (<code>if</code> <20> l'envers), qui marque la fin de
|
|
|
|
|
la boucle.</li>
|
|
|
|
|
</ol>
|
|
|
|
|
|
|
|
|
|
<pre>if <em>commande</em> ; then <em>commandes</em> ; else <em>commandes</em> ; fi</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue"> ou bien (car le point et virgule <20>quivaut <20> un saut
|
|
|
|
|
de ligne) :</p>
|
|
|
|
|
|
|
|
|
|
<pre>if <em>commande</em>
|
|
|
|
|
then <em>commandes</em>
|
|
|
|
|
else <em>commandes</em>
|
|
|
|
|
fi</pre>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Par exemple, pour Robert le jardinier, on aura :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<pre>if [[ $USER == "Robert"]]
|
|
|
|
|
then hacher_menu
|
|
|
|
|
else echo "Quand tu seras grand, $USER."
|
|
|
|
|
echo "Et fais bien attention en traversant la rue."
|
|
|
|
|
fi</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h4>La boucle <code>for</code></h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
La boucle <code>for</code> affecte successivement une variable chaque
|
|
|
|
|
cha<EFBFBD>ne de caract<63>res trouv<75>e dans une <em>liste de cha<68>nes</em>, et
|
|
|
|
|
ex<EFBFBD>cute les <em>commandes</em> une fois pour chaque cha<68>ne.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>for <em>var</em> in <em>liste de cha<68>nes</em> ; do <em>commandes</em> ; done</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue"> ou bien :</p>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
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,
|
2005-05-28 13:05:39 +02:00
|
|
|
|
s<EFBFBD>par<EFBFBD>es par des points et virgules (<code>;</code>) ou des retours <20> la
|
|
|
|
|
ligne.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Exemple :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<pre>for i in *; do echo "$i"; done</pre>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<p class="continue">
|
|
|
|
|
affiche les noms de tous les fichiers du r<>pertoire courant, un par ligne.
|
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
|
|
|
|
Remarque : plus un programme grossit, plus il importe que son
|
|
|
|
|
contenu soit lisible. <strong>Les noms de variable doivent donc <20>tre le
|
|
|
|
|
plus lisibles possible</strong>, pour permettre <20> d'autres gens, ou bien
|
|
|
|
|
<EFBFBD> vous-m<>me dans quelques mois, de comprendre rapidement votre script.
|
|
|
|
|
Ainsi, il peut <20>tre plus explicite d'<27>crire, au lieu de <20> <code>for
|
|
|
|
|
i in *; do echo "$i"; done</code> <3B> :
|
|
|
|
|
</p>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<pre>for fichier in *; do echo "$fichier"; done</pre>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
En outre, pour des raisons de lisibilit<69>, <strong>n'h<>sitez pas <20>
|
|
|
|
|
gaspiller des lignes de code</strong> en sautant des lignes ; les
|
|
|
|
|
lignes de code ne sont pas une ressource rare :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<pre>for fichier in *
|
|
|
|
|
do echo "$fichier"
|
|
|
|
|
done</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h4>La boucle <code>while</code></h4>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<pre>while <em>commande</em>
|
|
|
|
|
do <em>commande</em>
|
|
|
|
|
done</pre>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
La boucle <code>while</code> ex<65>cute les <em>commandes</em> de mani<6E>re
|
|
|
|
|
r<EFBFBD>p<EFBFBD>t<EFBFBD>e tant que la premi<6D>re <em>commande</em> r<>ussit.</p>
|
|
|
|
|
|
|
|
|
|
<p> Par exemple : <em>tant que</em> le mot de passe correct n'a pas
|
|
|
|
|
<EFBFBD>t<EFBFBD> donn<6E>, refuser l'acc<63>s et redemander le mot de passe.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h4>La boucle <code>case</code></h4>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<pre>case <em>cha<68>ne</em> in
|
|
|
|
|
<em>pattern</em>) <em>commande</em> ;;
|
|
|
|
|
<em>pattern</em>) <em>commande</em> ;;
|
|
|
|
|
esac</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
La boucle <code>case</code> ex<65>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> (motif) est un mot contenant <20>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 :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
case $var in
|
|
|
|
|
[0-9]*) echo 'Nombre';;
|
|
|
|
|
[a-zA-Z]*) echo 'Mot';;
|
|
|
|
|
*) echo 'Autre chose';;
|
|
|
|
|
esac</pre>
|
|
|
|
|
|
2005-05-28 13:05:39 +02:00
|
|
|
|
<p>
|
|
|
|
|
Vous observerez que l'on cl<63>t la boucle <code>case</code> avec
|
|
|
|
|
<code>esac</code>, qui est le mot <code>case</code> <20> l'envers, de m<>me
|
|
|
|
|
que l'on cl<63>t <code>if</code> avec <code>fi</code>.
|
|
|
|
|
</p>
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<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
|
2005-05-28 13:05:39 +02:00
|
|
|
|
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.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Les commandes <code>if</code> et <code>while</code> consid<69>rent donc le
|
|
|
|
|
code de retour 0 comme <20> vrai <3B>, et tout autre code comme
|
|
|
|
|
<EFBFBD> faux <3B>.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Il existe une commande <code>test</code>, qui <20>value des expressions
|
|
|
|
|
bool<EFBFBD>ennes (c'est-<2D>-dire dont la valeur ne peut <20>tre que vraie ou
|
|
|
|
|
fausse, 1 ou 0) pass<73>es en argument, et renvoie un code de retour en
|
|
|
|
|
fonction du r<>sultat. Elle est bien utile pour les scripts.
|
|
|
|
|
Exemple :
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</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>
|
|
|
|
|
|
2002-12-16 23:26:43 +01:00
|
|
|
|
<p>Vous <20>tes maintenant en mesure de faire ces <a
|
|
|
|
|
href="&url.tuteurs;unix/exercices/">exercices</a> pour vous
|
|
|
|
|
entra<EFBFBD>ner.</p>
|
|
|
|
|
|
2002-11-23 16:58:15 +01:00
|
|
|
|
|
|
|
|
|
<div class="metainformation">
|
|
|
|
|
Bas<EFBFBD> sur un polycopi<70> de Roberto Di Cosmo, Xavier Leroy et Damien Doligez.
|
2005-05-28 13:05:39 +02:00
|
|
|
|
Ajustements : Nicolas George. Compl<70>ments : Baptiste M<>l<EFBFBD>s.
|
|
|
|
|
Derni<EFBFBD>re modification le <date value="$Date: 2005-05-28 11:05:39 $" />.
|
2002-11-23 16:58:15 +01:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|