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>Entr<74>e/sortie</title>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
|
|
|
|
|
<h1>Entr<74>e, sortie, redirection</h1>
|
|
|
|
|
|
|
|
|
|
<h2><a name="redirections">Entr<74>e et sortie</a></h2>
|
|
|
|
|
|
|
|
|
|
<h3>Que sont l'entr<74>e et la sortie d'une commande ?</h3>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
2005-09-08 01:00:03 +02:00
|
|
|
|
<p> Prenons un programme <code>hachoir</code>, par exemple : on y
|
2005-05-31 13:33:37 +02:00
|
|
|
|
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>
|
|
|
|
|
|
|
|
|
|
<h3>Sortie standard et sortie d'erreur</h3>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Comportement par d<>faut</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
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>
|
|
|
|
|
|
|
|
|
|
<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.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h2>Les redirections</h2>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Nous allons <20>tudier successivement :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
<li> comment rediriger la sortie d'une commande vers un
|
|
|
|
|
fichier ;</li>
|
|
|
|
|
|
|
|
|
|
<li> comment ajouter la sortie d'une commande <20> la fin d'un
|
|
|
|
|
fichier ;</li>
|
|
|
|
|
|
|
|
|
|
<li> comment utiliser un fichier comme entr<74>e d'une commande ;</li>
|
|
|
|
|
|
|
|
|
|
<li> comment utiliser la sortie d'une commande comme entr<74>e d'une
|
|
|
|
|
autre.</li>
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Ces diff<66>rentes configurations esquissent la grammaire d'une utilisation
|
|
|
|
|
tr<EFBFBD>s performante des fonctionnalit<69>s du shell ; <strong>vous saurez
|
|
|
|
|
en effet comment brancher un fichier sur l'entr<74>e ou sur la sortie d'une
|
|
|
|
|
commande, et comment brancher la sortie d'une commande sur l'entr<74>e
|
|
|
|
|
d'une autre</strong>. Il n'y a pas d'autre combinaison possible.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Rediriger la sortie dans un fichier<65>: <code>></code></h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
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 :
|
|
|
|
|
</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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Ajouter la sortie <20> un fichier<65>: <code>>></code></h3>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Rediriger l'entr<74>e<EFBFBD>: <code><</code></h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
On peut aussi rediriger l'entr<74>e standard d'une commande (caract<63>re
|
|
|
|
|
<EFBFBD> <code><</code> <3B>). La commande lira alors le fichier au
|
|
|
|
|
lieu du clavier. Exemple :
|
|
|
|
|
</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>
|
|
|
|
|
|
|
|
|
|
<h3>Connecter la sortie d'une commande sur l'entr<74>e d'une autre<72>:
|
|
|
|
|
<code>|</code></h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
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
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre><span class="prompt">chaland ~ $</span> ls -l | less</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Le pipe, ou tube, est d'un usage tr<74>s courant, et rend beaucoup de
|
|
|
|
|
services.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Succ<63>s et erreur</h2>
|
|
|
|
|
|
|
|
|
|
<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 :
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
2005-09-08 01:00:03 +02:00
|
|
|
|
<p>
|
|
|
|
|
Pour en savoir plus sur les structures de test, consultez la page sur
|
|
|
|
|
les <a href="test.html">tests et calculs arithm<68>tiques</a>.
|
|
|
|
|
</p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Redirection des sorties standard et d'erreur</h2>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|
|
<table class="tableau">
|
|
|
|
|
<tr>
|
|
|
|
|
<th> Fonction </th>
|
|
|
|
|
<th> Bourne shell (sh, bash) </th>
|
|
|
|
|
<th> Z-shell (zsh) </th>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td>Redirige la sortie d'erreur (2) et la sortie standard (1) sur l'entr<74>e
|
|
|
|
|
de la commande suivante</td>
|
|
|
|
|
<td><code>2>&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>
|
|
|
|
|
|
|
|
|
|
<h3>Remarques</h3>
|
|
|
|
|
|
|
|
|
|
<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>
|
2005-07-05 09:18:06 +02:00
|
|
|
|
<li><a href="&url.tuteurs;unix/fichiers.html#less">more</a> (ou
|
|
|
|
|
<code>less</code>, bien plus <20>volu<6C>) <20> la fin du pipe-line, affiche le
|
|
|
|
|
r<EFBFBD>sultat page par page, pour laisser le temps de le lire. </li>
|
|
|
|
|
|
|
|
|
|
<li><a href="&url.tuteurs;unix/divers.html#wc">wc</a> compte le nombre
|
|
|
|
|
de caract<63>res, de mots et de lignes de son entr<74>e. </li>
|
|
|
|
|
|
|
|
|
|
<li><a href="&url.tuteurs;unix/chercher.html#grep">grep</a> cherche dans
|
|
|
|
|
son entre les lignes contenant un mot donn<6E>, et les <20>crit sur sa sortie.
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</li>
|
2005-07-05 09:18:06 +02:00
|
|
|
|
|
|
|
|
|
<li><a href="&url.tuteurs;unix/exercices/enchainer.html#syst">sort</a>
|
|
|
|
|
lit toutes les lignes de son entr<74>e, les trie, et les <20>crit dans l'ordre
|
|
|
|
|
sur sa sortie. Par d<>faut l'ordre est alphab<61>tique. </li>
|
|
|
|
|
|
|
|
|
|
<li><a href="&url.tuteurs;unix/fichiers.html#head">tail</a> <20>crit sur sa
|
|
|
|
|
sortie les derni<6E>res lignes de son entr<74>e. </li>
|
|
|
|
|
|
|
|
|
|
<li><a href="&url.tuteurs;unix/fichiers.html#head">head</a> <20>crit sur sa
|
|
|
|
|
sortie les premi<6D>res lignes de son entr<74>e. </li>
|
|
|
|
|
|
|
|
|
|
<li><a href="&url.tuteurs;unix/fichiers.html#cat">cat</a> copie
|
|
|
|
|
plusieurs fichiers sur sa sortie. </li>
|
|
|
|
|
|
2005-05-31 13:33:37 +02:00
|
|
|
|
<li><code>fold</code> coupe les lignes de son
|
|
|
|
|
entr<EFBFBD>e <20> 80 caract<63>res et <20>crit le r<>sultat sur sa sortie.
|
|
|
|
|
</li>
|
2005-07-05 09:18:06 +02:00
|
|
|
|
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
<h3>Exemples</h3>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|
|
<h2>R<>capitulatif</h2>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
La panoplie compl<70>te des redirections est la suivante :
|
|
|
|
|
</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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<p>Vous <20>tes maintenant en mesure de faire ces <a
|
|
|
|
|
href="&url.tuteurs;unix/exercices/">exercices</a> pour vous
|
2005-09-08 01:00:03 +02:00
|
|
|
|
entra<EFBFBD>ner. Ou bien vous pouvez revenir <20> la <a href="index.html">page
|
|
|
|
|
centrale sur le shell</a>, d'o<> vous pourrez vous orienter vers d'autres
|
|
|
|
|
parties du cours.</p>
|
2005-05-31 13:33:37 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="metainformation">
|
|
|
|
|
Bas<EFBFBD> sur un polycopi<70> de Roberto Di Cosmo, Xavier Leroy et Damien Doligez.
|
|
|
|
|
Modifications : Nicolas George, Baptiste M<>l<EFBFBD>s.
|
2005-09-08 01:00:03 +02:00
|
|
|
|
Derni<EFBFBD>re modification le <date value="$Date: 2005-09-07 23:00:04 $" />.
|
2005-05-31 13:33:37 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|