511 lines
17 KiB
HTML
511 lines
17 KiB
HTML
|
<?xml version="1.0" encoding="UTF-8"?>
|
|||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|||
|
<head>
|
|||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|||
|
<title>Fonctions</title>
|
|||
|
<link rel="stylesheet" href="../../tuteurs.css" type="text/css" />
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<div class="navigation">
|
|||
|
<h1>Tuteurs informatique<br /><a href="../../meta/contact.html">Nous contacter</a></h1>
|
|||
|
<hr />
|
|||
|
<ul class="menu">
|
|||
|
<li>
|
|||
|
<a href="../../meta/charte_graphique.html">Utiliser ce site</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="../../actualite.html">Actu et stages</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="../../docs/">Docs à imprimer</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="../../meta/plan_site.html">Plan du site</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="../../search.html">Rechercher</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<hr />
|
|||
|
<ul class="arbre">
|
|||
|
<li>
|
|||
|
<a href="../../">Les tuteurs</a>
|
|||
|
<ul class="arbre">
|
|||
|
<li>
|
|||
|
<a href="../">Unix</a>
|
|||
|
<ul class="arbre">
|
|||
|
<li>
|
|||
|
<a href="./">Shell</a>
|
|||
|
<ul class="arbre">
|
|||
|
<li>
|
|||
|
<a href="boucle.html">Boucles</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="commande.html">Commandes</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="entreesortie.html">Entrée/sortie</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="fonction.html" class="actuel">Fonctions</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="presentation.html">Présentation</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="script.html">Scripts</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="test.html">Tests</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="variable.html">Variables</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<hr />
|
|||
|
<ul class="menu">
|
|||
|
<li>
|
|||
|
<a href="http://www.eleves.ens.fr/">Serveur des élèves</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="http://www.ens.fr/">ENS</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="http://www.spi.ens.fr/">SPI</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
<div class="corps">
|
|||
|
<h1>Les fonctions en shell</h1>
|
|||
|
<div class="sommaire">
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<a href="#s1">Pourquoi des fonctions ?</a>
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<a href="#s1_1">Un programme sans fonction</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s1_2">Problèmes des programmes sans fonction</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s2">Définition et appel d'une fonction</a>
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<a href="#s2_1">Analogies avec le monde humain</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s2_2">Définir une fonction</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s2_3">Appeler une fonction</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s2_4">Les appels entre fonctions</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s3">Abusez des fonctions</a>
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<a href="#s3_1">Gain de lisibilité</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s3_2">Gain d'efficacité</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s3_3">Gain de souplesse</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
<p>
|
|||
|
Vous savez qu'<strong>un script shell n'est rien d'autre qu'une série de
|
|||
|
commandes</strong> (si vous ne le savez pas, lisez la page d'<a href="script.html">initiation à la programmation en shell</a>). Mais
|
|||
|
parfois cela pose des problèmes, car lorsqu'un script devient un peu
|
|||
|
long et surtout lorsqu'il est obligé de se répéter, les risques de
|
|||
|
bogues (dysfonctionnements) croissent.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
L'usage des <strong>fonctions</strong> permet de :
|
|||
|
</p>
|
|||
|
<ol>
|
|||
|
<li> éviter ces répétitions ;</li>
|
|||
|
<li> diminuer les risques de bogues ;</li>
|
|||
|
<li> augmenter la lisibilité du script pour un humain.</li>
|
|||
|
</ol>
|
|||
|
<h2>
|
|||
|
<a name="s1" id="s1">Pourquoi des fonctions ?</a>
|
|||
|
</h2>
|
|||
|
<h3>
|
|||
|
<a name="s1_1" id="s1_1">Un programme sans fonction</a>
|
|||
|
</h3>
|
|||
|
<p>
|
|||
|
Utilisateur de TeX ou <a href="../../logiciels/latex/">LaTeX</a>
|
|||
|
(ou non), vous voulez effacer régulièrement tous les fichiers
|
|||
|
<code>.aux</code> et <code>.log</code> qui polluent vos répertoires.
|
|||
|
Pour ceux qui ne connaissent pas TeX, sachez que ce sont des fichiers
|
|||
|
construits automatiquement, et que l'on peut recréer facilement à partir
|
|||
|
du fichier <code>.tex</code> : les supprimer permet donc de gagner
|
|||
|
de l'espace disque sans dommages.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
Votre script ressemble donc à ceci :
|
|||
|
</p>
|
|||
|
<pre>
|
|||
|
#!/bin/sh
|
|||
|
|
|||
|
# fichier "texcleaner" : efface les fichiers aux et log
|
|||
|
|
|||
|
# Je prends chaque fichier .aux du répertoire courant
|
|||
|
for fichier in *.aux
|
|||
|
do
|
|||
|
# J'affiche son nom et demande confirmation pour l'effacer
|
|||
|
echo "$fichier"
|
|||
|
echo "Voulez-vous vraiment l'effacer ? (o/n)"
|
|||
|
|
|||
|
# Je lis la réponse de l'utilisateur
|
|||
|
read reponse
|
|||
|
|
|||
|
# Et s'il dit oui, j'efface
|
|||
|
if [[ $reponse == "o" ]]
|
|||
|
then rm -f $fichier
|
|||
|
fi
|
|||
|
done
|
|||
|
|
|||
|
# Je prends chaque fichier .log du répertoire courant
|
|||
|
for fichier in *.log
|
|||
|
do
|
|||
|
# J'affiche son nom et demande confirmation pour l'effacer
|
|||
|
echo "$fichier"
|
|||
|
echo "Voulez-vous vraiment l'effacer ? (o/n)"
|
|||
|
|
|||
|
# Je lis la réponse de l'utilisateur
|
|||
|
read reponse
|
|||
|
|
|||
|
# Et s'il dit oui, j'efface
|
|||
|
if [[ $reponse == "o" ]]
|
|||
|
then rm -f $fichier
|
|||
|
fi
|
|||
|
done
|
|||
|
</pre>
|
|||
|
<p>
|
|||
|
Vous venez de terminer ce programme, et vous êtes content, car il
|
|||
|
fonctionne comme vous le voulez.
|
|||
|
</p>
|
|||
|
<div class="encadre">
|
|||
|
Soyons honnêtes : cet exemple est un peu tiré par les cheveux, car
|
|||
|
il existe une commande très simple pour faire cela :
|
|||
|
<pre>
|
|||
|
rm -i *.aux *.log
|
|||
|
</pre>
|
|||
|
|
|||
|
Mais ici, cet exemple <em>à la limite</em> est là pour illustrer d'une
|
|||
|
façon simple l'intérêt des fonctions... Disons alors que cet exemple
|
|||
|
permet de donner une version francisée de la commande
|
|||
|
<code>rm -i *.aux *.log</code> !
|
|||
|
</div>
|
|||
|
<h3>
|
|||
|
<a name="s1_2" id="s1_2">Problèmes des programmes sans fonction</a>
|
|||
|
</h3>
|
|||
|
<p>
|
|||
|
Ce programme présente certains aspects déplaisants :
|
|||
|
</p>
|
|||
|
<ol>
|
|||
|
<li> il n'est pas très lisible ;</li>
|
|||
|
<li> il comporte des répétitions relativement longues (une dizaine de
|
|||
|
lignes) ;</li>
|
|||
|
<li> si vous voulez changer le moindre détail, vous devrez rechercher <i>à
|
|||
|
la main</i> toutes les occurrences de ce que vous voulez changer, ce
|
|||
|
qui :
|
|||
|
<ol><li> est <strong>fatigant</strong> ;</li><li> est <strong>fastidieux</strong> ;</li><li> est, surtout, <strong>très peu fiable</strong> : si vous
|
|||
|
oubliez une occurrence ou que vous modifiez un endroit alors qu'il ne le
|
|||
|
fallait pas, les conséquences peuvent être graves.</li></ol>
|
|||
|
</li>
|
|||
|
</ol>
|
|||
|
<p>
|
|||
|
Il faudrait, pour pallier ces inconvénients, trouver un moyen de
|
|||
|
<strong>centraliser les informations destinées à être répétées, afin que
|
|||
|
l'on puisse s'y référer à chaque endroit où cela est
|
|||
|
nécessaire</strong>. C'est pour cela que les fonctions existent.
|
|||
|
</p>
|
|||
|
<h2>
|
|||
|
<a name="s2" id="s2">Définition et appel d'une fonction</a>
|
|||
|
</h2>
|
|||
|
<p>
|
|||
|
L'utilisation des fonctions se fait en deux moments :
|
|||
|
</p>
|
|||
|
<ol>
|
|||
|
<li> d'abord, il faut <strong>définir la fonction</strong> : vous
|
|||
|
décrivez quelle série de commandes il faudra exécuter lorsque l'on
|
|||
|
appellera la fonction ;</li>
|
|||
|
<li> ensuite, il faut <strong>appeler la fonction</strong> à chaque
|
|||
|
endroit que vous voulez.</li>
|
|||
|
</ol>
|
|||
|
<h3>
|
|||
|
<a name="s2_1" id="s2_1">Analogies avec le monde humain</a>
|
|||
|
</h3>
|
|||
|
<p>
|
|||
|
Dans le monde naturel, on peut comparer cela à l'horloge parlante :
|
|||
|
celle-ci commence par dire « au quatrième top, il sera neuf heures
|
|||
|
cinquante-deux », puis « top... top... top... top. »
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
On pourrait dire que dans un premier temps, l'horloge parlante
|
|||
|
<em>définit une fonction</em>, en assignant un signal (le quatrième top)
|
|||
|
à ce qu'il signale (il est neuf heures cinquante-deux) ; une fois
|
|||
|
cela clairement défini, l'horloge <em>égrène les quatre
|
|||
|
« top »</em>, et le quatrième renvoie à l'énoncé « il est
|
|||
|
neuf heures cinquante-deux ».
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
En langage naturel, définir une fonction équivaut à dire :
|
|||
|
<em>quand je dirai le nom de la fonction, vous l'exécuterez</em>. C'est
|
|||
|
un acte de langage, comme quand un arbitre dit aux athlètes :
|
|||
|
« Go ! » ; car tous les athlètes savent que le
|
|||
|
signifiant « Go ! » (ou le coup de pistolet tiré en
|
|||
|
l'air) signifie qu'ils doivent partir (la fonction a été définie dans
|
|||
|
le règlement officiel de leur sport).
|
|||
|
</p>
|
|||
|
<h3>
|
|||
|
<a name="s2_2" id="s2_2">Définir une fonction</a>
|
|||
|
</h3>
|
|||
|
<h4>Comment définir les fonctions ?</h4>
|
|||
|
<p>
|
|||
|
Définir une fonction est extrêmement simple :
|
|||
|
</p>
|
|||
|
<pre>
|
|||
|
nom () {
|
|||
|
instruction1
|
|||
|
instruction2
|
|||
|
...
|
|||
|
}
|
|||
|
</pre>
|
|||
|
<ol>
|
|||
|
<li>
|
|||
|
On commence par <strong>trouver un nom à la fonction</strong>. Vous
|
|||
|
pouvez choisir ce nom à votre guise, par exemple
|
|||
|
<code>liste_des_fichiers</code>, <code>effacer_fichier</code>, etc. Il
|
|||
|
est toutefois fortement recommandé :
|
|||
|
|
|||
|
<ul><li> de <strong>ne pas donner à ses fonctions des noms de commandes
|
|||
|
existant déjà</strong>, par exemple <code>ls</code>, <code>mutt</code>,
|
|||
|
etc. Cela pourrait en effet poser de graves problèmes, car les fonctions
|
|||
|
définies dans un programme sont prioritaires sur les commandes integrées
|
|||
|
du shell (<code>cd</code>, <code>alias</code>, etc.) et les commandes
|
|||
|
externes (<code>mutt</code>, <code>mozilla</code>, etc.). Le
|
|||
|
comportement devient difficilement prévisible, et surtout, le script
|
|||
|
sera très difficile à débuguer... </li><li> de <strong>ne pas utiliser de signes de ponctuation, d'espaces ni
|
|||
|
de caractères accentués</strong> dans les noms de fonction ;</li></ul>
|
|||
|
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
une fois que vous avez donné un nom à la fonction, notez des
|
|||
|
<strong>parenthèses ouvrante et fermante</strong> : ce sont elles
|
|||
|
qui indiquent à l'interpréteur du script qu'il s'agit d'une définition
|
|||
|
de fonction ;
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
enfin, <strong>entre accolades</strong>, notez la <strong>série des
|
|||
|
instructions</strong> qu'il faudra exécuter à chaque appel de la
|
|||
|
fonction.
|
|||
|
</li>
|
|||
|
</ol>
|
|||
|
<h4>Où définir les fonctions ?</h4>
|
|||
|
<p>
|
|||
|
Comme l'interpréteur de scripts shell lit des scripts ligne à ligne,
|
|||
|
<strong>il faut que la fonction soit définie avant d'être
|
|||
|
appelée</strong>. Sinon, vous recevez un message de type :
|
|||
|
« Command not found » (commande introuvable). Par convention,
|
|||
|
il est préférable de <strong>placer <em>toutes</em> les définitions de
|
|||
|
fonction vers le début du programme</strong>, avant toutes les
|
|||
|
instructions.
|
|||
|
</p>
|
|||
|
<h3>
|
|||
|
<a name="s2_3" id="s2_3">Appeler une fonction</a>
|
|||
|
</h3>
|
|||
|
<p>
|
|||
|
Notre programme sera donc considérablement allégé :
|
|||
|
</p>
|
|||
|
<pre>
|
|||
|
#!/bin/sh
|
|||
|
|
|||
|
# fichier "texcleaner" : efface les fichiers aux et log
|
|||
|
|
|||
|
# Je définis ma fonction effacer_fichier
|
|||
|
|
|||
|
effacer_fichier () {
|
|||
|
# J'affiche son nom et demande confirmation pour l'effacer
|
|||
|
echo "$1"
|
|||
|
echo "Voulez-vous vraiment l'effacer ? (o/n)"
|
|||
|
|
|||
|
# Je lis la réponse de l'utilisateur
|
|||
|
read reponse
|
|||
|
|
|||
|
# Et s'il dit oui, j'efface
|
|||
|
if [[ $reponse == "o" ]]
|
|||
|
then rm -f $1
|
|||
|
fi
|
|||
|
}
|
|||
|
|
|||
|
# Je prends chaque fichier .aux du répertoire courant
|
|||
|
for fichier in *.aux
|
|||
|
do
|
|||
|
# J'appelle la fonction effacer_fichier pour chaque fichier
|
|||
|
effacer_fichier $fichier
|
|||
|
done
|
|||
|
|
|||
|
# Je prends chaque fichier .log du répertoire courant
|
|||
|
for fichier in *.log
|
|||
|
do
|
|||
|
# J'appelle la fonction effacer_fichier pour chaque fichier
|
|||
|
effacer_fichier $fichier
|
|||
|
done
|
|||
|
</pre>
|
|||
|
<p>
|
|||
|
On économise une dizaine de lignes, on gagne en lisibilité, et les
|
|||
|
risques de bogues diminuent considérablement car s'il y a des
|
|||
|
corrections à apporter, c'est à un seul endroit du script, et non d'une
|
|||
|
façon disséminée sur l'ensemble du programme.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
Un détail de la fonction <code>effacer_fichier</code> peut vous
|
|||
|
étonner : nous utilisons l'argument <code>$1</code>. Comme vous le
|
|||
|
savez sans doute (sinon, lisez la page sur
|
|||
|
les <a href="commande.html">commandes shell et leurs
|
|||
|
arguments</a>), <code>$1</code> désigne le premier argument passé à une
|
|||
|
commande ; or <strong>les fonctions peuvent recevoir des
|
|||
|
arguments</strong>, exactement de la même façon que les commandes. C'est
|
|||
|
même tout à fait normal, car <strong>les fonctions sont en fait des
|
|||
|
commandes comme les autres, à ceci près qu'elles ne sont valables qu'à
|
|||
|
l'échelle d'un script</strong>, et non à celle d'un système tout entier.
|
|||
|
</p>
|
|||
|
<h3>
|
|||
|
<a name="s2_4" id="s2_4">Les appels entre fonctions</a>
|
|||
|
</h3>
|
|||
|
<p>
|
|||
|
Sachez enfin que <strong>des fonctions peuvent appeler d'autres
|
|||
|
fonctions</strong>, ce qui donne une extrême souplesse à leur
|
|||
|
utilisation.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
En voici un bref exemple :
|
|||
|
</p>
|
|||
|
<pre>
|
|||
|
#!/bin/sh
|
|||
|
|
|||
|
# Je définis une première fonction
|
|||
|
|
|||
|
ecrire_sur_une_ligne () {
|
|||
|
echo -n $*
|
|||
|
}
|
|||
|
|
|||
|
# Je définis une deuxième fonction qui appelle la première
|
|||
|
|
|||
|
saluer_utilisateur () {
|
|||
|
ecrire_sur_une_ligne "Bonjour "
|
|||
|
echo $USER
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
# J'appelle la deuxième fonction
|
|||
|
saluer_utilisateur
|
|||
|
|
|||
|
</pre>
|
|||
|
<h2>
|
|||
|
<a name="s3" id="s3">Abusez des fonctions</a>
|
|||
|
</h2>
|
|||
|
<p>
|
|||
|
De là, passons à un conseil de programmation : <strong>abusez des
|
|||
|
fonctions !</strong> N'hésitez pas à créer des fonctions pour tout
|
|||
|
et n'importe quoi. Vous en tirerez :
|
|||
|
</p>
|
|||
|
<ol>
|
|||
|
<li> un gain de lisibilité ;</li>
|
|||
|
<li> un gain d'efficacité ;</li>
|
|||
|
<li> un gain de souplesse.</li>
|
|||
|
</ol>
|
|||
|
<h3>
|
|||
|
<a name="s3_1" id="s3_1">Gain de lisibilité</a>
|
|||
|
</h3>
|
|||
|
<p><strong>Un programme sans fonction n'est lisible que s'il est très
|
|||
|
petit</strong> : une vingtaine de lignes tout au plus. Dès qu'un
|
|||
|
programme dépasse cette taille, il cesse d'être intelligible d'un seul
|
|||
|
coup d'œil pour un humain.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
Supposons qu'un programme soit amené à répéter <em>n</em> fois un
|
|||
|
même fragment de code comportant <em>p</em> lignes ; en
|
|||
|
utilisant des fonctions on économise
|
|||
|
(<em>n</em> - 1) x <em>p</em> lignes (toutes
|
|||
|
les occurrences de la répétition, moins la définition de la fonction).
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
Ce gain de lignes est indissociable d'un gain de lisibilité, car les
|
|||
|
répétitions fatiguent inutilement le cerveau humain.
|
|||
|
</p>
|
|||
|
<h3>
|
|||
|
<a name="s3_2" id="s3_2">Gain d'efficacité</a>
|
|||
|
</h3>
|
|||
|
<p>
|
|||
|
En recopiant « à la main » des fragments identiques de codes,
|
|||
|
vous risquez toujours la faute de frappe. Or, la moindre coquille peut
|
|||
|
avoir des conséquences, au mieux, imprévisibles ; au pire,
|
|||
|
catastrophiques.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
En isolant les séries d'instructions dans des définitions de fonctions,
|
|||
|
vous concentrez en un seul endroit la situation possible d'un bogue
|
|||
|
donné. Vous pouvez <em>circonscrire le bogue</em>.
|
|||
|
</p>
|
|||
|
<h3>
|
|||
|
<a name="s3_3" id="s3_3">Gain de souplesse</a>
|
|||
|
</h3>
|
|||
|
<p>
|
|||
|
En utilisant des fonctions, vous donnez à vos programmes une grande
|
|||
|
souplesse. Si vous voulez apporter une modification d'ensemble à un
|
|||
|
programme, vous n'avez plus à corriger autant de morceaux du script
|
|||
|
qu'il y a d'occurrences du même fragment : vous apportez vos
|
|||
|
modifications de manière centralisée.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
Pour décrire ce phénomène, on parle souvent de
|
|||
|
<strong>modularité</strong>, ou encore
|
|||
|
d'<strong>encapsulation</strong>. Il s'agit en effet de privilégier
|
|||
|
l'assemblage simple d'éléments simples à l'assemblage complexe
|
|||
|
d'éléments complexes. Ainsi, chaque fonction <em>cache</em> aux
|
|||
|
fonctions qui l'appellent la complexité de son travail, pour leur offrir
|
|||
|
une interface simple : le travail est divisé en autant de petites
|
|||
|
tâches que nécessaires, au lieu d'une seule tâche gigantesque et
|
|||
|
labyrinthesque.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
Pour toutes ces raisons, n'hésitez surtout pas à créer des fonctions et
|
|||
|
à les emboîter entre elles. La programmation vous paraîtra de plus en
|
|||
|
plus facile, à mesure que vous réaliserez des tâches de plus en plus
|
|||
|
complexes.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
Vous pouvez revenir à la <a href="index.html">page centrale sur le
|
|||
|
shell</a>, d'où vous pourrez vous orienter vers d'autres parties du
|
|||
|
cours.
|
|||
|
</p>
|
|||
|
<div class="metainformation">
|
|||
|
Auteur : Baptiste Mélès.
|
|||
|
Dernière modification : 2007-03-25 par Baptiste Mélès.
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</body>
|
|||
|
</html>
|