Capsule de théorie Redirection des entrées-sorties standard
- Introduction
- Entrée standard, sortie standard et erreur standard
- Redirections de la sortie standard.
- Redirections de la sortie standard.
- Redirections de la sortie et de l’entrée standard
- Redirection de la sortie d’erreur
- Redirections de la sortie standard d’une commande vers la sortie d’erreur
- Enchainement de commandes avec des tubes
Introduction
Dans les systèmes d’exploitation de type Unix ainsi que dans d’autres systèmes qui s’en sont inspirés (notamment ceux de Microsoft), un programme communique avec le terminal à travers des entrées-sorties qui lui sont présentées comme des fichiers à accès séquentiel. Chacun de ces fichiers est identifié par un numéro : 0 pour l’entrée standard (stdin), 1 pour la sortie standard (stdout), et 2 pour la sortie d’erreur standard (stderr).
Par défaut, lorsqu’on lance un programme depuis la ligne de commande, celui-ci reçoit les mêmes entrées-sorties que le shell. Ainsi, lorsqu’un programme lit des caractères sur l’entrée standard, ceux-ci proviennent en principe du terminal où ils ont été saisis au clavier, et lorsqu’il écrit des caractères dans la sortie standard ou dans la sortie d’erreur, ceux-ci sont envoyés au terminal qui effectue l’opération correspondant à chacun d’eux (imprimer le caractère, revenir à la ligne, actionner la cloche, positionner le curseur, changer la couleur, etc.). Mais le shell permet également de rediriger ces entrées-sorties vers d’autres fichiers et c’est ce que nous allons voir dans les lignes qui suivent.
Entrée standard, sortie standard et erreur standard
Lorsqu’un programme est lancé depuis la ligne de commande du shell, il reçoit les mêmes entrées-sorties que le shell. Celles-ci sont en principe liées au clavier et à l’écran du terminal comme l’illustre la figure 1.
Le programme cat
écrit dans la sortie standard les caractères qu’il reçoit de l’entrée standard. Si on lance ce programme sans autres arguments, on constate qu’il répète chaque ligne que vous saisissez, jusqu’à ce qu’il trouve un caractère EOF (fin de fichier) qu’on peut envoyer avec la combinaison de touches ctrl-D (^D
) ou que vous l’interrompiez avec ^C
.
1
2
3
4
5
6
dev@vmdev:~ cat
une ligne de texte
une ligne de texte
une autre ligne de texte
une autre ligne de texte
^D
On remarque que cat
ne répète pas chaque caractère, mais chaque ligne. Ce comportement n’est pas dû au programme, mais au terminal. En effet, si l’on ne précise rien, celui-ci accumule les caractères dans une mémoire tampon (buffer) et n’envoie les caractères que lorsque la touche Return est pressée. Ce mode de fonctionnement, appelé « cooked mode » par opposition à « raw mode », vous permet de corriger d’éventuelles fautes de frappe sur une ligne de texte avant de l’envoyer.
Redirections de la sortie standard.
Vous vous doutez certainement qu’il ne sert à rien de lancer la commande cat
comme nous venons de le faire. En revanche, en redirigeant la sortie standard avec l’opérateur de redirection >
, la commande cat
nous permet de saisir le contenu d’un fichier.
1
2
3
4
5
dev@vmdev:~ cat > data.txt
ligne 1
ligne 2
ligne 3
^D
Schématiquement, la situation est la suivante :
Lors de la redirection de la sortie standard à l’aide de l’opérateur >
vers un fichier déjà existant, les nouvelles données remplacent les données qu’il contient. Pour ajouter les nouvelles données à la suite des données existantes, on peut utiliser l’opérateur >>
.
Redirections de la sortie standard.
Si on redirige maintenant l’entrée standard avec l’opérateur de redirection <
, les données que reçoit le programme ne proviennent plus du clavier, mais d’un fichier comme le montre l’illustration de la figure 5.
Pour autant que la norme d’encodage du fichier corresponde à celle du terminal, en redirigeant l’entrée standard de la commande cat
on peut l’utiliser pour afficher le contenu d’un fichier. La commande ci-dessous à pour effet d’afficher le contenu du fichier data.txt.
1
dev@vmdev:~ cat < data.txt
PowerShell ne permet pas ce type de redirection. Pour passer le contenu d’un fichier à une commande, on peut lui passer le résultat de Get-Content
à travers un tube (voir la section 6).
Redirections de la sortie et de l’entrée standard
Il est également possible d’utiliser les deux opérateurs redirection <
et >
dans une même commande, pour rediriger à la fois l’entrée et la sortie standard. Par exemple, en redirigeant l’entrée et la sortie de cat
, on copie le fichier d’entrée dans le fichier de sortie.
L’utilisation de l’opérateur >>
avec cat
permet de concaténer le contenu de plusieurs fichiers.
Redirection de la sortie d’erreur
Lorsqu’une erreur survient, l’usage veut que le programme informe l’utilisateur en écrivant un message dans la sortie d’erreur standard. En principe, les caractères envoyés vers cette sortie sont envoyés vers le terminal, mais il possible de les rediriger vers un fichier. Pour cela, on utilise l’opérateur 2>
. Il s’agit en fait du même opérateur que pour la redirection de la sortie standard auquel on adjoint le numéro du fichier correspondant à la sortie à rediriger. Pour rediriger la sortie standard, on peut également utiliser l’opérateur 1>
.
Redirections de la sortie standard d’une commande vers la sortie d’erreur
Puisque la sortie standard et la sortie d’erreur standard sont des fichiers, on peut également rediriger l’une dans l’autre. Pour cela on utilise les opérateurs 2>
ou 1>
et au lieu de spécifier le nom d’un fichier on spécifie le numéro d’une sortie précédé d’un « et » commercial (&
). Par exemple, pour rediriger la sortie de standard de la commande echo
dans la sortie d’erreur, on écrira la commande suivante :
1
dev@vmdev:~ echo "message d’erreur" 1>&2
On peut utiliser ce type de redirection pour écrire un message d’erreur dans un script bash ou fichier de commande Windows. En PowerShell, ce type de redirection n’est pas possible, mais la commande Write-Error permet d’écrire explicitement dans la sortie d’erreur.
Enchainement de commandes avec des tubes
Dans un article paru en 1978 dans « The Bell System Technical Journal », Douglas McIlroy rassemble un certain nombre de maximes qui ont cours dans la communauté des programmeurs et des utilisateurs de Unix et qui en décrivent la philosophie. La première est sans doute la plus connue :
Mais voici ce que dit la deuxième :
La plupart des commandes Unix (internes ou externes) respecte ce précepte qui permet de les enchaîner à l’aide de tube (inventé par McIlroy) pour former un pipeline comme dans l’example suivant :
1
dev@vmdev:~ ls | sort
Le symbole |
(tube ou pipe) indique que l’on souhaite rediriger la sortie standard de la commande ls
vers l’entrée standard de la commande sort
comme l’illustre la figure 9.
Les tubes sont abondamment utilisés en PowerShell qui en a repris l’idée.