2005-05-31 13:33:37 +02: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>Scripts</title>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
|
|
|
|
|
<h1><a name="programmation">Programmation de scripts en shell</a></h1>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<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. </p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Cr<43>er un script</h2>
|
|
|
|
|
|
2005-07-05 09:18:06 +02:00
|
|
|
|
<h3><3E>crire un script</h3>
|
|
|
|
|
<p>
|
|
|
|
|
Un script shell est un fichier en mode texte. C'est-<2D>-dire que ce n'est
|
|
|
|
|
pas un fichier binaire, ex<65>cutable directement par la machine, mais
|
|
|
|
|
<strong>il doit <20>tre interpr<70>t<EFBFBD></strong>.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h4>L'interpr<70>tation d'un script</h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
L'interpr<70>tation signifie que chaque commande contenue dans un script
|
|
|
|
|
doit <20>tre lue par un programme, appel<65> <em>interpr<70>teur</em> (et non
|
|
|
|
|
interpr<EFBFBD>te, bizarrement) ; l'interpr<70>teur analyse chaque commande
|
|
|
|
|
du script et la traduit en langage machine, ce qui permet l'ex<65>cution du
|
|
|
|
|
script.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>Dans le cas des scripts shell, l'interpr<70>teur, c'est le shell
|
|
|
|
|
lui-m<>me. Dans d'autres langages, comme le Perl, l'interpr<70>teur est un
|
|
|
|
|
programme ind<6E>pendant du shell. </p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h4>L'<27>dition d'un script</h4>
|
|
|
|
|
<p>Un script <20>tant un fichier en mode texte, il doit <20>tre cr<63><72> avec un
|
|
|
|
|
<EFBFBD>diteur de texte. Un <20>diteur de texte est un programme dont la fonction
|
|
|
|
|
est... d'<27>diter du texte. Pour savoir plus <20> leur sujet, consultez les
|
|
|
|
|
pages sur les <a href="&url.tuteurs;unix/editeurs/"><3E>diteurs</a>. </p>
|
|
|
|
|
|
|
|
|
|
<p>Mais quel <20>diteur choisir ?</p>
|
|
|
|
|
|
|
|
|
|
<p> Tout d'abord, il faut savoir que <strong>n'importe quel <20>diteur est
|
|
|
|
|
capable d'ouvrir et d'<27>crire des scripts shell</strong>, et vous pouvez
|
|
|
|
|
tout <20> fait modifier avec n'importe quel <20>diteur de texte ce que vous
|
|
|
|
|
avez <20>crit avec n'importe quel autre.</p>
|
|
|
|
|
|
|
|
|
|
<p>Mais il faut savoir aussi que <strong>certains <20>diteurs de texte sont
|
|
|
|
|
plus appropri<72>s que d'autres <20> l'<27>criture de scripts shell</strong>. Par
|
|
|
|
|
exemple, <code>nano</code> permet d'<27>diter des scripts comme tout autre
|
|
|
|
|
<EFBFBD>diteur, mais quand un script fait plus d'une ligne, on commence <20> s'y
|
|
|
|
|
perdre un peu. <20> l'inverse, <code>emacs</code> et <code>vim</code>
|
|
|
|
|
offrent quelques fonctionnalit<69>s qui deviennent rapidement
|
|
|
|
|
indispensables :</p>
|
|
|
|
|
|
|
|
|
|
<ol>
|
|
|
|
|
<li> l'indentation ;</li>
|
|
|
|
|
<li> la coloration syntaxique.</li>
|
|
|
|
|
</ol>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h5>L'indentation</h5>
|
|
|
|
|
|
|
|
|
|
<p>L'indentation consiste <20> <20> a<>rer <3B> votre texte selon sa
|
|
|
|
|
construction logique. C'est tr<74>s utile, en particulier, quand on a un
|
|
|
|
|
script qui ressemble <20> ceci :</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
# Fichier "vote-nir"
|
|
|
|
|
|
|
|
|
|
echo "<3B>tes-vous favorable au remplacement du NIR par le
|
|
|
|
|
VIR ?"
|
|
|
|
|
select opinion in Pour Contre
|
|
|
|
|
do
|
|
|
|
|
case $opinion in
|
|
|
|
|
# Laisser passer ceux qui r<>pondent correctement <20> la question
|
|
|
|
|
"Pour"|"Contre") break;;
|
|
|
|
|
# Au cas o<> des zozos tapent sur autre chose que 1 ou 2
|
|
|
|
|
"*") continue;;
|
|
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# M'envoyer le r<>sultat par mail
|
|
|
|
|
echo "$opinion" | mail bourdieu
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>M<>me (surtout) si vous ne comprenez pas ce que tout cela veut dire,
|
|
|
|
|
vous conviendrez que ce n'est pas tr<74>s lisible. Comparez donc avec
|
|
|
|
|
ceci : </p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
# Fichier "vote-nir"
|
|
|
|
|
|
|
|
|
|
echo "<3B>tes-vous favorable au remplacement du NIR par le
|
|
|
|
|
VIR ?"
|
|
|
|
|
select opinion in Pour Contre
|
|
|
|
|
do
|
|
|
|
|
case $opinion in
|
|
|
|
|
# Laisser passer ceux qui r<>pondent correctement <20> la
|
|
|
|
|
question
|
|
|
|
|
"Pour"|"Contre") break;;
|
|
|
|
|
|
|
|
|
|
# Au cas o<> des zozos tapent sur autre chose que 1 ou 2
|
|
|
|
|
"*") continue;;
|
|
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# M'envoyer le r<>sultat par mail
|
|
|
|
|
echo "$opinion" | mail bourdieu
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>Les deux scripts sont interpr<70>t<EFBFBD>s exactement de la m<>me fa<66>on :
|
|
|
|
|
l'interpr<70>teur ignore les espaces et les lignes vides. Mais avec
|
|
|
|
|
l'indentation, on per<65>oit imm<6D>diatement (en tout cas, beaucoup plus
|
|
|
|
|
vite) la structure logique du script.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h5>La coloration syntaxique</h5>
|
|
|
|
|
<p>Les <20>diteurs comme <code>emacs</code> et <code>vim</code> analysent
|
|
|
|
|
automatiquement le statut des diff<66>rents mots et symboles que vous tapez
|
|
|
|
|
et les colorent logiquement. Par exemple, avec emacs, vous pouvez
|
|
|
|
|
avoir :</p>
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
<li> les commentaires en rouge ;</li>
|
|
|
|
|
<li> les noms de commande en bleu fonc<6E> ;</li>
|
|
|
|
|
<li> les noms d'arguments en vert ;</li>
|
|
|
|
|
<li> les noms de variables en jaune ;</li>
|
|
|
|
|
<li> les instructions li<6C>es aux boucles en bleu clair ;</li>
|
|
|
|
|
<li> etc.</li>
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
<p><3E>a n'a l'air de rien, dit comme cela, mais comparez vous-m<>me et vous
|
|
|
|
|
verrez que ces outils sont indispensables, et que l'on y gagne au moins
|
|
|
|
|
la moiti<74> du temps d'<27>criture et de d<>bugage.</p>
|
|
|
|
|
|
|
|
|
|
<h5>Apprendre <code>emacs</code> ou <code>vim</code></h5>
|
|
|
|
|
|
|
|
|
|
<p>Apprenez donc, si ce n'est pas d<>j<EFBFBD> le cas, les commandes de base
|
|
|
|
|
d'emacs ou de vim, ce sont des outils quasi incontournables au
|
|
|
|
|
programmeur shell, surtout d<>butant.</p>
|
|
|
|
|
|
|
|
|
|
<p> Heureusement, les tuteurs vous ont concoct<63> des pages
|
|
|
|
|
d'initiation : le <a
|
|
|
|
|
href="&url.tuteurs;unix/editeurs/emacs.html">tutorial
|
|
|
|
|
<code>emacs</code></a> et le <a
|
|
|
|
|
href="&url.tuteurs;unix/editeurs/vim.html">tutorial
|
|
|
|
|
<code>vim</code></a>.</p>
|
|
|
|
|
|
|
|
|
|
<p>Vous h<>sitez entre <code>emacs</code> et <code>vim</code> ? Tout
|
|
|
|
|
le monde est pass<73> par l<>. Jetez un coup d'œil <20> chacun des deux,
|
|
|
|
|
puis concentrez-vous sur celui qui vous para<72>t le plus sympathique et le
|
|
|
|
|
plus pratique ; et si vous h<>sitez encore, tirez-en un au
|
|
|
|
|
sort, ils se valent vraiment.</p>
|
|
|
|
|
|
|
|
|
|
|
2005-05-31 13:33:37 +02:00
|
|
|
|
<h3>Rendre un script ex<65>cutable</h3>
|
|
|
|
|
|
2005-07-05 09:18:06 +02:00
|
|
|
|
<p> Pour que le shell sache comment l'interpr<70>ter, un script shell doit
|
|
|
|
|
commencer par la ligne: </p>
|
2005-05-31 13:33:37 +02: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
|
|
|
|
|
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 :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<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
|
2005-07-05 09:18:06 +02:00
|
|
|
|
page sur <a href="&url.tuteurs;unix/droits.html">les droits
|
|
|
|
|
d'acc<63>s</a>).
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Le chemin d'une commande</h3>
|
|
|
|
|
<p>
|
|
|
|
|
Pour comprendre ce qui suit, vous devez savoir ce qu'est le
|
|
|
|
|
<code>PATH</code>. Si ce n'est pas le cas, lisez la <a
|
2005-07-05 09:18:06 +02:00
|
|
|
|
href="presentation.html">pr<70>sentation du shell</a>.
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Quand vous ex<65>cutez un script, vous pouvez vous trouver <20>
|
|
|
|
|
n'importe quel endroit de l'arborescence de vos r<>pertoires. Si le
|
|
|
|
|
r<EFBFBD>pertoire courant ne se situe pas dans votre <code>PATH</code> et
|
|
|
|
|
que vous voulez ex<65>cuter un programme qui s'y trouve, vous ne pouvez
|
|
|
|
|
pas taper :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">clipper ~</span> commande
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">car si le r<>pertoire courant n'est pas dans le
|
|
|
|
|
<code>PATH</code>, le shell n'ira pas y chercher
|
|
|
|
|
<code>commande</code>. </p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Vous recevrez donc un message comme :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">clipper ~</span> commande
|
|
|
|
|
zsh: command not found: commande</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h4>Sp<53>cifier le chemin d'une commande</h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Pour que le shell comprenne o<> chercher votre commande, il faut donc
|
|
|
|
|
sp<EFBFBD>cifier l'emplacement de la commande en donnant son chemin, qu'il
|
|
|
|
|
soit absolu :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">clipper ~</span> /home/toto/repertoire/courant/commande
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">ou relatif : </p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">clipper ~</span> repertoire/courant/commande
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">ou encore sous la forme : </p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">clipper ~/repertoire/courant</span> ./commande
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h4>Le r<>pertoire <code>~/bin</code></h4>
|
|
|
|
|
<p>
|
|
|
|
|
Il y a un certain nombre de commandes que l'on peut vouloir utiliser
|
|
|
|
|
depuis n'importe quel r<>pertoire. Dans ce cas, il est fastidieux de :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
<li> devoir se rappeler dans quel r<>pertoire se trouve chacune
|
|
|
|
|
d'entre elles ;</li>
|
|
|
|
|
<li> devoir taper <20> chaque fois le chemin de la commande.</li>
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
<p>Il suffit donc de mettre tous vos scripts dans un m<>me
|
|
|
|
|
r<EFBFBD>pertoire, et de mettre ce r<>pertoire dans le
|
|
|
|
|
<code>PATH</code>. Par convention, ce r<>pertoire s'appelle
|
|
|
|
|
<code>bin</code> et se place dans votre r<>pertoire personnel. Si
|
|
|
|
|
votre r<>pertoire personnel est <code>/home/toto</code>, ce
|
|
|
|
|
r<EFBFBD>pertoire sera donc <code>/home/toto/bin</code>. </p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Commencez donc par cr<63>er ce r<>pertoire :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">clipper ~</span> mkdir bin
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Ensuite, v<>rifiez qu'il soit bien dans votre <code>PATH</code> :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">clipper ~</span> echo $PATH
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">Si vous voyez par exemple <code>$HOME/bin</code>
|
|
|
|
|
dans votre <code>PATH</code>, alors c'est bon, tous les fichiers
|
|
|
|
|
ex<EFBFBD>cutables situ<74>s dans ce r<>pertoire seront accessibles depuis
|
|
|
|
|
n'importe quel r<>pertoire.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Si ce n'est pas le cas, il faut ajouter ce r<>pertoire au
|
|
|
|
|
<code>PATH</code>. Pour cela, ajoutez dans le fichier de configuration
|
|
|
|
|
de votre shell, par exemple le fichier <code>.zshrc</code>, la
|
|
|
|
|
ligne :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>PATH=$PATH:$HOME/bin</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">Cette ligne indique que la prochaine fois que vous
|
|
|
|
|
ouvrirez votre shell, le r<>pertoire <code>bin</code> figurera dans
|
|
|
|
|
votre <code>PATH</code>.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h2>Principes g<>n<EFBFBD>raux des scripts shell</h2>
|
|
|
|
|
|
|
|
|
|
<h3>Une succession de commandes</h3>
|
|
|
|
|
|
|
|
|
|
<p> Si vous manipulez d<>j<EFBFBD> le shell en ligne de commande, vous
|
|
|
|
|
pouvez commencer vos premiers scripts. Un script shell est en effet
|
|
|
|
|
avant tout une <strong>succession de commandes</strong>.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p> Par exemple, si vous avez coutume de taper successivement, quand
|
|
|
|
|
vous vous loguez <20> l'ENS :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<span class="prompt">clipper ~</span> mozilla &
|
|
|
|
|
<span class="prompt">clipper ~</span> mutt
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">vous pouvez vous cr<63>er le script suivant dans le
|
|
|
|
|
fichier <code>~/bin/amorce</code> :</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
|
|
mozilla &
|
|
|
|
|
mutt
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>Ainsi, d<>s que vous vous connectez, vous pouvez taper
|
|
|
|
|
<code>amorce</code> dans le shell, et vos commandes s'ex<65>cuteront
|
|
|
|
|
automatiquement. </p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Commentaires</h3>
|
|
|
|
|
<p>
|
|
|
|
|
Presque tous les langages informatiques autorisent d'ins<6E>rer des
|
|
|
|
|
commentaires ; le shell n'<27>chappe pas <20> la r<>gle. Pour
|
|
|
|
|
cela, il suffit de faire pr<70>c<EFBFBD>der chaque ligne de commentaire du
|
|
|
|
|
caract<EFBFBD>re <20> # <3B>. Exemple :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
|
|
# Tout ce que j'<27>cris ici ne sera pas lu.
|
|
|
|
|
echo "Ce que je tape ici sera lu."
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Les lignes blanches ne sont pas interpr<70>t<EFBFBD>es non
|
|
|
|
|
plus. N'h<>sitez donc surtout pas <20> espacer votre script, les
|
|
|
|
|
lignes blanches ne consomment presque rien en termes d'espace disque, ce
|
|
|
|
|
n'est donc pas une ressource rare.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h3>L'imp<6D>ratif de lisibilit<69></h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Pourquoi espacer son script ? Pourquoi ins<6E>rer des
|
|
|
|
|
commentaires ? Pour une seule et m<>me raison :
|
|
|
|
|
<strong>votre script doit <20>tre lisible</strong>. Pourquoi <20>tre
|
|
|
|
|
lisible ? </p>
|
|
|
|
|
|
|
|
|
|
<p> D'abord, pour autrui : si d'autres gens lisent votre script, il
|
|
|
|
|
doit <20>tre intelligible, et les passages complexes doivent <20>tre
|
|
|
|
|
explicit<EFBFBD>s par des commentaires.</p>
|
|
|
|
|
|
|
|
|
|
<p> Ensuite, pour vous-m<>me ; au moment o<> vous <20>crivez un
|
|
|
|
|
script, vous comprenez tout, naturellement ; mais si vous le
|
|
|
|
|
relisez dans quelques mois, voire quelques ann<6E>es, les passages
|
|
|
|
|
obscurs risqueront d'<27>tre incompr<70>hensibles, ce qui est
|
|
|
|
|
particuli<EFBFBD>rement p<>nible quand on essaye de <em>d<>buguer</em>
|
|
|
|
|
un programme, c'est-<2D>-dire d'en corriger les erreurs.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<h2>Un script qui parle : la commande <code>echo</code></h2>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
<p>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
Maintenant que vous savez comment on peut ex<65>cuter un script, il s'agit
|
|
|
|
|
de le remplir... Commen<65>ons par ce qu'il y a de plus simple :
|
|
|
|
|
afficher du texte.
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<h3>Hello World !</h3>
|
|
|
|
|
|
2005-05-31 13:33:37 +02:00
|
|
|
|
<p>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
Traditionnellement, on commence par faire un programme qui affiche
|
|
|
|
|
simplement la ligne <20> Hello world <3B> (ce qui signifie en
|
|
|
|
|
anglais : bonjour au monde entier). Faites donc un fichier
|
|
|
|
|
<code>helloworld</code> contenant les lignes suivantes :
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
# Fichier "helloworld"
|
|
|
|
|
echo "Hello world"
|
|
|
|
|
</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
Ex<EFBFBD>cutez ensuite ce programme, par exemple en tapant, dans le r<>pertoire
|
|
|
|
|
o<EFBFBD> il se trouve :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre><span class="prompt">clipper ~ $</span> ./helloworld
|
|
|
|
|
Hello world</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<EFBFBD>a y est, vous avez cr<63><72> votre premier programme ! Lancez-le autant
|
|
|
|
|
de vous que vous voulez, vous avez bien m<>rit<69> d'<27>tre fier de vous.
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<p>
|
|
|
|
|
Exercice : francisez ce script.
|
|
|
|
|
</p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<h3>La commande <code>echo</code></h3>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
La commande <code>echo</code> sert <20> afficher du texte sur la sortie
|
|
|
|
|
standard (pour savoir ce qu'est la sortie standard, consultez la page
|
|
|
|
|
sur les <a href="entreesortie.html">entr<74>es et sorties</a>). Chaque
|
|
|
|
|
ligne de texte est <20>crite sur une ligne <20> part. Exemple :
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
# Fichier "bonjour"
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
echo "Bonjour... "
|
|
|
|
|
echo "Comment allez-vous ?"
|
|
|
|
|
</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<p class="continue">affiche les lignes suivantes :</p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<pre>
|
|
|
|
|
Bonjour...
|
|
|
|
|
Comment allez-vous ?
|
|
|
|
|
</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<p class="continue">et non :</p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<pre>
|
|
|
|
|
Bonjour... Comment allez-vous ?
|
|
|
|
|
</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<h4>Annuler le retour chariot</h4>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
Si vous voulez annuler le retour chariot qui a lieu par d<>faut <20> la fin
|
|
|
|
|
de toute commande <code>echo</code>, il faut utiliser l'option
|
|
|
|
|
<code>-n</code>. Le programme sera alors :
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
echo -n "Bonjour..."
|
|
|
|
|
echo "Comment allez-vous ?"
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p class="continue">
|
|
|
|
|
Alors seulement, vous pourrez avoir :
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<pre>
|
|
|
|
|
Bonjour... Comment allez-vous ?
|
|
|
|
|
</pre>
|
|
|
|
|
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<h4>Citer des variables</h4>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<p>Faisons mieux encore : votre script va citer des variables. Pour
|
|
|
|
|
savoir ce que sont des variables, allez voir la page sur les <a
|
|
|
|
|
href="variable.html">variables</a>.</p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<p>La variable <code>USER</code> contient le login de
|
|
|
|
|
l'utilisateur ; la variable <code>PWD</code> (pour <em>print
|
|
|
|
|
working directory</em>) affiche le r<>pertoire courant. Faisons donc le
|
|
|
|
|
script suivant :</p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<pre>
|
|
|
|
|
#/bin/sh
|
|
|
|
|
# Fichier "mon-pwd"
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
echo "Bonjour $USER..."
|
|
|
|
|
echo "Tu es actuellement dans le r<>pertoire $PWD."
|
|
|
|
|
</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<p>Comme vous pouvez le remarquer, pour citer le contenu d'une variable,
|
|
|
|
|
on ajoute le signe dollar ($) devant son nom.</p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<h2>Un script qui <20>coute : la commande <code>read</code></h2>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<p>Parler c'est bien, <20>couter c'est mieux. Jusqu'ici, votre programme
|
|
|
|
|
est capable de parler, de dire bonjour, mais il n'est m<>me pas capable
|
|
|
|
|
de vous appeler par votre nom, tout juste par votre login, ce qui n'est
|
|
|
|
|
pas tr<74>s intime...</p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
Nous allons donc lui donner la facult<6C> d'<27>couter, gr<67>ce <20> la commande
|
|
|
|
|
<code>read</code>. Prenons le script suivant :
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
#!/bin/sh
|
|
|
|
|
# Fichier "mon-nom"
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
echo "Bonjour... Comment vous-appelez-vous ?"
|
|
|
|
|
read nom
|
|
|
|
|
echo "Je vous souhaite, $nom, de passer une bonne journ<72>e."
|
|
|
|
|
</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<p>Vous connaissez d<>j<EFBFBD> la commande <code>echo</code>. La commande
|
|
|
|
|
<code>read</code> permet de lire des variables. Si vous ex<65>cutez ce
|
|
|
|
|
script, apr<70>s avoir affich<63> la ligne </p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<pre>
|
|
|
|
|
Bonjour... Comment vous-appelez-vous ?
|
|
|
|
|
</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
<p class="continue">le shell va attendre que vous tapiez votre
|
|
|
|
|
nom. Tapez par exemple <code>Toto</code>, puis appuyez sur Entr<74>e, et
|
|
|
|
|
vous verrez :</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
Bonjour... Comment vous-appelez-vous ?
|
|
|
|
|
<em>Toto</em>
|
|
|
|
|
Je vous souhaite, Toto, de passer une bonne journ<72>e.</pre>
|
|
|
|
|
|
|
|
|
|
<div class="attention">
|
|
|
|
|
La commande <code>read</code> doit <20>tre suivie du seul nom de la
|
|
|
|
|
variable, <strong>non pr<70>c<EFBFBD>d<EFBFBD> du signe dollar</strong>. <em>Le signe
|
|
|
|
|
dollar ne doit pr<70>c<EFBFBD>der le nom de la variable que lorsque l'on cite son
|
|
|
|
|
contenu.</em>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h3>Lire plusieurs variables</h3>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
<p>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
La commande <code>read</code> permet <20>galement de lire plusieurs
|
|
|
|
|
variables. Il suffit pour cela d'indiquer <20> la suite les noms des
|
|
|
|
|
diff<EFBFBD>rentes variables. Exemple :
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
2005-06-03 15:56:21 +02:00
|
|
|
|
#!/bin/sh
|
|
|
|
|
# Fichier "administration"
|
|
|
|
|
|
|
|
|
|
echo "<3B>crivez votre nom puis votre pr<70>nom :"
|
|
|
|
|
read nom prenom
|
|
|
|
|
echo "Nom : $nom"
|
|
|
|
|
echo "Pr<50>nom : $prenom"
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>Vous aurez :</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<EFBFBD>crivez votre nom puis votre pr<70>nom :
|
|
|
|
|
<em>Hugo Victor</em>
|
|
|
|
|
Nom : Hugo
|
|
|
|
|
Pr<EFBFBD>nom : Victor
|
|
|
|
|
</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
|
2005-06-03 15:56:21 +02:00
|
|
|
|
|
|
|
|
|
<h3>Appuyer sur Entr<74>e pour continuer</h3>
|
|
|
|
|
|
|
|
|
|
<p>Nous avons vu comment utiliser <code>read</code> avec un seul
|
|
|
|
|
argument et avec plusieurs arguments ; il reste <20> voir l'usage de
|
|
|
|
|
<code>read</code> <em>sans</em> argument. Oui, c'est possible !
|
|
|
|
|
Cela <20>quivaut simplement <20> attendre un r<>action de l'utilisateur, mais
|
|
|
|
|
sans m<>moriser ce qu'il tape.</p>
|
|
|
|
|
|
|
|
|
|
<p> Concr<63>tement, cela est tr<74>s utile apr<70>s un message <20> Appuyez
|
|
|
|
|
sur Entr<74>e pour continuer. <3B> Exemple :</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
# Fichier "continuer"
|
|
|
|
|
|
|
|
|
|
echo "Quelle est la diff<66>rence entre un canard ?"
|
|
|
|
|
echo "(Appuyez sur Entr<74>e pour avoir la r<>ponse)"
|
|
|
|
|
read
|
|
|
|
|
echo "Les pattes, surtout la gauche."
|
|
|
|
|
</pre>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
2005-09-07 12:03:49 +02:00
|
|
|
|
<h2>Poursuivre l'apprentissage de la programmation shell</h2>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Vous connaissez maintenant les bases de la programmation en shell. Vous
|
|
|
|
|
avza d<>j<EFBFBD> de quoi <20>crire de nombreux scripts qui peuvent vous faciliter
|
|
|
|
|
la vie de tous les jours. Pour cela, lorsque vous ressentez un besoin,
|
|
|
|
|
ne vous demandez pas si vous avez les connaissances requises pour <20>crire
|
|
|
|
|
un programme donn<6E>, mais plut<75>t <em>comment, <20> partir de vos
|
|
|
|
|
connaissances actuelles, vous pourriez le r<>aliser</em>.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Pour poursuivre votre apprentissage, vous pouvez passer <20> la lecture des
|
|
|
|
|
pages suivanets :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
<li> <a href="entreesortie.html">entr<74>e, sortie,
|
|
|
|
|
redirection</a> ;</li>
|
|
|
|
|
|
|
|
|
|
<li> <a href="test.html">test et calcul arithm<68>tique</a> ;</li>
|
|
|
|
|
|
|
|
|
|
<li> <a href="boucle.html">boucles et structures de
|
|
|
|
|
contr<EFBFBD>le</a> ;</li>
|
|
|
|
|
|
|
|
|
|
<li> <a href="fonction.html">d<>finir et appeler des fonctions</a>.</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
<div class="metainformation">
|
2005-06-03 15:56:21 +02:00
|
|
|
|
Auteur : Baptiste M<>l<EFBFBD>s.
|
2005-09-07 12:03:49 +02:00
|
|
|
|
Derni<EFBFBD>re modification le <date value="$Date: 2005-09-07 10:03:54 $" />.
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|