Entrée, sortie, redirection

Entrée et sortie

Que sont l'entrée et la sortie d'une commande ?

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'informatique.

Prenons un programme hachoir, 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.

Deux concepts permettent de modéliser cette transformation d'informations : les concepts d'entrée et de sortie. L'entrée, c'est la vache ou les carottes ; la sortie, c'est le steak haché ou les carottes rapées.

Sortie standard et sortie d'erreur

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 messages normaux relevant de la transformation d'informations (par exemple le steak haché ou les carottes rapées), mais il y a aussi des messages d'erreur.

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 sortie standard et la sortie d'erreur.

Comportement par défaut

Pour résumer, chaque commande a donc :

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.

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.

Les redirections

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.

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é.

Ou encore, vous pouvez donner un plant de carottes comme entrée au programme cueillette, et envoyer la sortie (c'est-à-dire les carottes cueillies) au programme hachoir.

Nous allons étudier successivement :

Ces différentes configurations esquissent la grammaire d'une utilisation très performante des fonctionnalités du shell ; 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. Il n'y a pas d'autre combinaison possible.

Rediriger la sortie dans un fichier : >

On peut rediriger la sortie standard d'une commande vers un fichier (caractère « > »). Le résultat de la commande sera placé dans le fichier au lieu de s'afficher sur l'écran. Exemple :

chaland ~ $ ls -l > foo

Le résultat de ls -l ne s'affiche pas à l'écran, mais il est placé dans le fichier foo. On peut alors taper

chaland ~ $ less foo

(ou more foo) pour lire le fichier page par page.

Ajouter la sortie à un fichier : >>

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

chaland ~ $ ls -l > foo

à chaque fois, le contenu antérieur du fichier foo est écrasé par le contenu ultérieur.

Pour éviter cela, il existe l'outil de redirection >>. Ainsi, si vous tapez plusieurs fois

chaland ~ $ ls -l >> foo

le fichier foo contiendra à la suite tout ce que vous a renvoyé la commande.

Rediriger l'entrée : <

On peut aussi rediriger l'entrée standard d'une commande (caractère « < »). La commande lira alors le fichier au lieu du clavier. Exemple :

chaland ~ $ elm leroy < foo

envoie par mail à Xavier Leroy le résultat de la commande ls -l de tout à l'heure.

On peut aussi taper more < foo qui est équivalent à more foo car more sans argument lit son entrée standard et l'affiche page par page sur le terminal.

Connecter la sortie d'une commande sur l'entrée d'une autre : |

Il devient rapidement ennuyeux de taper :

chaland ~ $ ls -l > foo
chaland ~ $ less < foo
chaland ~ $ rm foo

On peut se passer du fichier intermédiaire (foo dans notre exemple) grâce à un pipe (caractère « | »). 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

chaland ~ $ ls -l | less

Le pipe, ou tube, est d'un usage très courant, et rend beaucoup de services.

Succès et erreur

On a parfois besoin de savoir si une commande a réussi ou non avant d'en lancer une autre. Les indicateurs && et || permettent, respectivement, de lancer une commande si (et seulement si) la précédente a réussi ou échoué.

Par exemple, si j'ai un fichier foo, j'obtiens :

chaland ~ $ ls foo && echo "J'ai un fichier foo."
foo
J'ai un fichier foo.

Si je n'ai pas de fichier foo, le message ne s'affiche pas. En revanche, si je tape alors :

chaland ~ $ ls foo || echo "Je n'ai pas de fichier foo."
ls: foo: No such file or directory
Je n'ai pas de fichier foo.

Pour en savoir plus sur les structures de test, consultez la page sur les tests et calculs arithmétiques.

Redirection des sorties standard et d'erreur

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 2>&1 avant la redirection.

Fonction Bourne shell (sh, bash) Z-shell (zsh)
Redirige la sortie d'erreur (2) et la sortie standard (1) sur l'entrée de la commande suivante 2>&1 | |&
Redirige la sortie d'erreur et la sortie standard vers fichier >fichier 2>&1 >& fichier
Redirige la sortie d'erreur et la sortie standard à la fin de fichier >>fichier 2>&1 >>& fichier

Remarques

Normalement, une redirection avec > 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.

Une ligne de commandes contenant des | s'appelle un pipe-line. Quelques commandes souvent utilisées dans les pipe-lines sont:

Exemples

cat glop buz > toto

Concatène les fichiers glop et buz et place le résultat dans toto.

wc -w /usr/dict/words

Affiche le nombre de mots du dictionnaire Unix.

grep gag /usr/dict/words | tail

Affiche les 10 derniers mots du dictionnaire qui contiennent la chaîne gag.

Récapitulatif

La panoplie complète des redirections est la suivante :

Vous êtes maintenant en mesure de faire ces exercices pour vous entraîner. Ou bien vous pouvez revenir à la page centrale sur le shell, d'où vous pourrez vous orienter vers d'autres parties du cours.

Basé sur un polycopié de Roberto Di Cosmo, Xavier Leroy et Damien Doligez. Modifications : Nicolas George, Baptiste Mélès.