400 lines
12 KiB
XML
400 lines
12 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE html
|
||
PUBLIC "-//ENS/Tuteurs//DTD TML 1//EN"
|
||
"tuteurs://DTD/tml.dtd">
|
||
<html>
|
||
<head>
|
||
<title>Entrée/sortie</title>
|
||
</head>
|
||
<body>
|
||
|
||
<h1>Entrée, sortie, redirection</h1>
|
||
|
||
<h2><a name="redirections">Entrée et sortie</a></h2>
|
||
|
||
<h3>Que sont l'entrée et la sortie d'une commande ?</h3>
|
||
|
||
<p>
|
||
Un programme consiste à traiter des données, et à renvoyer des données
|
||
transformées : il transforme des informations, et c'est pourquoi
|
||
l'on parle d'<em>informatique</em>.</p>
|
||
|
||
<p> Prenons un 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ères. Par
|
||
exemple, on fait entrer une vache, il en ressort du steak haché ;
|
||
on y fait entrer des carottes, il en ressort des carottes rapées.
|
||
</p>
|
||
|
||
<p>
|
||
Deux concepts permettent de modéliser cette transformation
|
||
d'informations : les concepts d'entrée et de
|
||
sortie. L'<strong>entrée</strong>, c'est la vache ou les carottes ;
|
||
la <strong>sortie</strong>, c'est le steak haché ou les carottes
|
||
rapées.
|
||
</p>
|
||
|
||
<h3>Sortie standard et sortie d'erreur</h3>
|
||
|
||
<p>
|
||
Mais cette première distinction entre entrée et sortie ne suffit pas,
|
||
car la sortie d'un programme, c'est-à-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é ou les
|
||
carottes rapé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çu, devra vous prévenir qu'il n'arrive pas à hacher un objet si
|
||
gros. Et ce message, quoiqu'il sorte aussi bien du hachoir que le steak
|
||
haché, ne doit pas être traité de la même façon à sa sortie, et n'est
|
||
pas suivi des mêmes consé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é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ée standard est le clavier, la sortie standard est
|
||
l'écran, et la sortie d'erreur est aussi l'écran.</p>
|
||
|
||
<p> C'est sur le clavier que vous tapez ; ce que vous tapez et ce
|
||
que renvoient les programmes s'inscrit à l'écran ; les messages
|
||
d'erreur renvoyés par les programmes s'affichent à l'é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 à fait orienter différemment
|
||
vos programmes.</p>
|
||
|
||
<p> Par exemple, si vous donnez une vache comme entrée au hachoir, vous
|
||
pouvez orienter la sortie vers une imprimante (au lieu de l'écran,
|
||
proposé par défaut), et vous imprimerez ainsi du steak haché. </p>
|
||
|
||
<p>
|
||
Ou encore, vous pouvez donner un plant de carottes comme entrée au
|
||
programme <code>cueillette</code>, et envoyer la sortie (c'est-à-dire
|
||
les carottes cueillies) au programme <code>hachoir</code>.
|
||
</p>
|
||
|
||
<p>
|
||
Nous allons étudier successivement :
|
||
</p>
|
||
|
||
<ul>
|
||
<li> comment rediriger la sortie d'une commande vers un
|
||
fichier ;</li>
|
||
|
||
<li> comment ajouter la sortie d'une commande à la fin d'un
|
||
fichier ;</li>
|
||
|
||
<li> comment utiliser un fichier comme entrée d'une commande ;</li>
|
||
|
||
<li> comment utiliser la sortie d'une commande comme entrée d'une
|
||
autre.</li>
|
||
</ul>
|
||
|
||
<p>
|
||
Ces différentes configurations esquissent la grammaire d'une utilisation
|
||
très performante des fonctionnalités du shell ; <strong>vous saurez
|
||
en effet comment brancher un fichier sur l'entrée ou sur la sortie d'une
|
||
commande, et comment brancher la sortie d'une commande sur l'entrée
|
||
d'une autre</strong>. Il n'y a pas d'autre combinaison possible.
|
||
</p>
|
||
|
||
|
||
<h3>Rediriger la sortie dans un fichier : <code>></code></h3>
|
||
|
||
<p>
|
||
On peut <em> rediriger</em> la sortie standard d'une commande vers un
|
||
fichier (caractère « <code>></code> »). Le résultat de la
|
||
commande sera placé dans le fichier au lieu de s'afficher sur l'é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 à l'écran, mais il est placé
|
||
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 à un fichier : <code>>></code></h3>
|
||
|
||
<p> On veut parfois ajouter la sortie d'un programme à un fichier, sans
|
||
effacer ce qui précè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">
|
||
à chaque fois, le contenu antérieur du fichier <code>foo</code> est
|
||
écrasé par le contenu ultérieur.
|
||
</p>
|
||
|
||
<p>
|
||
Pour é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>à la suite</em> tout ce que
|
||
vous a renvoyé la commande.
|
||
</p>
|
||
|
||
|
||
|
||
|
||
<h3>Rediriger l'entrée : <code><</code></h3>
|
||
|
||
<p>
|
||
On peut aussi rediriger l'entrée standard d'une commande (caractère
|
||
« <code><</code> »). 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 à Xavier Leroy le résultat de la commande <code>ls -l</code> de
|
||
tout à l'heure.
|
||
</p>
|
||
|
||
<p>
|
||
On peut aussi taper <code>more < foo</code> qui est équivalent à
|
||
<code>more foo</code> car <code>more</code> sans argument lit son entrée
|
||
standard et l'affiche page par page sur le terminal.
|
||
</p>
|
||
|
||
<h3>Connecter la sortie d'une commande sur l'entrée d'une autre :
|
||
<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édiaire (<code>foo</code> dans notre
|
||
exemple) grâce à un <em>pipe</em> (caractère
|
||
« <code>|</code> »). Un pipe connecte directement la sortie
|
||
standard d'une commande sur l'entrée standard d'une autre commande.
|
||
Exemple : pour afficher page par page la liste des fichiers du
|
||
répertoire courant, faire
|
||
</p>
|
||
|
||
<pre><span class="prompt">chaland ~ $</span> ls -l | less</pre>
|
||
|
||
<p>
|
||
Le pipe, ou tube, est d'un usage très courant, et rend beaucoup de
|
||
services.
|
||
</p>
|
||
|
||
|
||
|
||
<h2>Succè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écédente a réussi ou échoué.
|
||
</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>
|
||
|
||
<p>
|
||
Pour en savoir plus sur les structures de test, consultez la page sur
|
||
les <a href="test.html">tests et calculs arithmétiques</a>.
|
||
</p>
|
||
|
||
|
||
<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é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 à 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à 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ées dans les pipe-lines sont:
|
||
</p>
|
||
|
||
<ul>
|
||
<li><a href="&url.tuteurs;unix/fichiers.html#less">more</a> (ou
|
||
<code>less</code>, bien plus évolué) à la fin du pipe-line, affiche le
|
||
ré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ères, de mots et de lignes de son entrée. </li>
|
||
|
||
<li><a href="&url.tuteurs;unix/chercher.html#grep">grep</a> cherche dans
|
||
son entrée les lignes contenant un mot donné, et les écrit sur sa sortie.
|
||
</li>
|
||
|
||
<li><a href="&url.tuteurs;unix/exercices/enchainer.html#syst">sort</a>
|
||
lit toutes les lignes de son entrée, les trie, et les écrit dans l'ordre
|
||
sur sa sortie. Par défaut l'ordre est alphabétique. </li>
|
||
|
||
<li><a href="&url.tuteurs;unix/fichiers.html#head">tail</a> écrit sur sa
|
||
sortie les dernières lignes de son entrée. </li>
|
||
|
||
<li><a href="&url.tuteurs;unix/fichiers.html#head">head</a> écrit sur sa
|
||
sortie les premières lignes de son entrée. </li>
|
||
|
||
<li><a href="&url.tuteurs;unix/fichiers.html#cat">cat</a> copie
|
||
plusieurs fichiers sur sa sortie. </li>
|
||
|
||
<li><code>fold</code> coupe les lignes de son
|
||
entrée à 80 caractères et écrit le résultat sur sa sortie.
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
<h3>Exemples</h3>
|
||
|
||
<pre>cat glop buz > toto</pre>
|
||
|
||
<p>
|
||
Concatène les fichiers <code>glop</code> et <code>buz</code> et place le
|
||
ré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îne
|
||
<code>gag</code>.
|
||
</p>
|
||
|
||
<h2>Récapitulatif</h2>
|
||
|
||
<p>
|
||
La panoplie complète des redirections est la suivante :
|
||
</p>
|
||
|
||
<ul>
|
||
<li><code>></code> : change la sortie standard de la commande pour la placer
|
||
dans un fichier.
|
||
</li>
|
||
<li><code><</code> : change l'entrée standard de la commande pour la prendre
|
||
dans un fichier.
|
||
</li>
|
||
<li><code>|</code> : branche la sortie standard de la commande de gauche sur
|
||
l'entrée standard de la commande de droite.
|
||
</li>
|
||
<li><code>>></code> : change la sortie standard pour l'ajouter à la fin
|
||
d'un fichier existant.
|
||
</li>
|
||
<li><code>||</code> : exécuter la commande suivante si la première a
|
||
échoué.
|
||
</li>
|
||
<li><code>&&</code> : n'exécuter la commande suivante que si la
|
||
première a réussi.
|
||
</li>
|
||
</ul>
|
||
|
||
|
||
|
||
<p>Vous êtes maintenant en mesure de faire ces <a
|
||
href="&url.tuteurs;unix/exercices/">exercices</a> pour vous
|
||
entraîner. Ou bien 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">
|
||
Basé sur un polycopié de Roberto Di Cosmo, Xavier Leroy et Damien Doligez.
|
||
Modifications : Nicolas George, Baptiste Mélès.
|
||
<date value="from git" />
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|