Les programmes et les commandes lancées
sous UNIX ont automatiquement à leur
disposition une entrée standard (appelée standard in
ou stdin
) et une sortie standard (appelée, sans grande
surprise, standard out
ou stdout
). Par
défaut, l'entrée standard est le clavier (c'est-à-dire que les
programmes lisent les données entrées au clavier par l'utilisateur) et
la sortie standard est l'écran (c'est à dire qu'un printf() dans un de
nos programmes C va résulter en quelque chose de visible à
l'écran).
Cette connexion initiale de l'entrée standard vers le clavier et de la
sortie standard vers l'écran n'a cependant rien de fatal ou
d'obligatoire. Il est possible avant et pendant l'execution d'un
programme, de reconnecter stdin
et stdout
avec autre chose, que ce soit un fichier ou une entrée ou sortie d'un
autre programme. La suite de cette page décrit quelques-unes des
possibilités.
Les deux opérateurs <
et >
permettent de
rediriger l'entrée ou la sortie standard d'un programme vers un
fichier juste avant son lancement.
>
La commande suivante:
ordi:~ > date > toto.txt
n'affiche rien à l'écran, alors que la commande date
affiche normalement la date et l'heure. Mais le
fichier toto.txt
contient maintenant la date! Si on
s'imagine un programme comme une boite avec un tube d'entrée et un
tube de sortie (voir aussi l'encadré "Comment faire en sorte que..."),
l'effet de l'opérateur de redirection >
est de connecter
le tube sortie sur le fichier toto.txt
, alors que
normalement il aurait été connecté à l'écran (au terminal).
Il faut faire attention au fait que le contenu précédent
de toto.txt
est perdu si on lance une commande en
redirigant la sortie vers lui: toto.txt
contiendra la
sortie de la commande lancée, mais plus rien de ce qu'il contenait
avant.
Cette redirection marche pour tous les programmes, y compris ce que vous avez écrit:
ordi:~ > ls -l > toto.txt ordi:~ > cat toto.txt # affiche le contenu de toto.txt ordi:~ > ./simul_pendule.exe > pendule.data
Ceci est très pratique, car vous n'avez plus besoin de vous préoccuper
de l'ouverture d'un fichier et de l'utilisation
de fprintf()
. À la place, vous écrivez le programme en
utilisant printf()
pour que les résultats s'affichent à
l'écran, et vous les redirigez vers un fichiers une fois que vous êtes
satisfait du résultat. Derrière les
coulisses, printf(...)
n'est de toute façon rien d'autre
que fprintf(stdout,...)
, que vous pourriez parfaitement
utiliser à la place. Cela vous évite d'avoir à penser
au fopen()/fclose()
.
Comment faire en sorte que ...
... les messages d'information ou d'erreur du programme ne soient pas eux aussi redirigé vers le fichier en même temps que les données ?
Réponse: Chaque programme est en fait équipé d'office d'une deuxième
sortie appelée standard error
ou stderr
qui
n'est pas redirigé par l'opérateur >
. Il suffit donc
d'imprimer les message dans ce tube
(avec fprintf(stderr,...)
) pour qu'ils arrivent à
l'écran!
... le contenu préalable du fichier soit conservé, et que la sortie d'une commande soit juste ajoutée à la fin ?
Réponse: il suffit pour cela d'utiliser l'opérateur >>
à
la place de l'opérateur >
.
<
L'operateur <
permet de rediriger l'entrée standard
d'un programme (ou d'une commande) qui a besoin qu'on lui donne des
information, usuellement données au clavier. Cet opérateur permet de
préparer les informations que l'on veut donner au programme en les
écrivant dans un fichier texte (par
exemple parametres.txt
) puis d'appeler le programme en
redirigeant l'entrée vers le fichier :
ordi:~ > programme < parametres.txt
Au lieu d'attendre que l'utilisateur entre les données requises au
clavier, il va les chercher dans le
fichier parametres.txt
. Ce type de fonctionnement permet
de gagner beaucoup de temps lorsque le programme nécessite de
nombreuses entrées, cela permet également de changer les paramètres
d'exécution du programme en ne changeant que ce qui est nécessaire
dans le fichier d'entrées. Cela limite énormément les fautes de
frappe!
Il existe un opérateur de redirection qui connecte la sortie d'un
programme à l'entrée d'un autre programme. Les données "coulent" donc
depuis le premier programme par ce qu'on appelle un "tube"
(pipe
en Anglais) vers l'entrée du deuxième programme.
L'opérateur est un trait vertical |
entre les programmes.
L'intérêt de ce comportement et de pouvoir enchaîner des
transformations de données. On appelle filtre tout programme qui lit
depuis l'entrée standard, transforme les données, puis les écrit vers
la sortie standard. Ainsi, la plupart des programmes et commandes UNIX
sont des filtres. L'opérateur |
permet de les enchaîner
en envoyant la sortie de l'un vers l'entrée de l'autre:
ordi:~ > ls -l | more
Par exemple, si le répertoire courant contient un grand nombre
de fichiers dont on veut voir la liste détaillée, la commande
ls -l
n'est pas satisfaisante car son résultat défile sur
l'écran et on ne peut voir les premiers fichiers de la liste. Nous
avons vu que l'on pouvait rediriger la sortie de cette commande vers
un fichier (ls -l > toto.txt
), mais il faut ensuite taper
la commande more toto.txt
pour observer le résultat écran
par écran, puis effacer le fichier toto.txt
(rm
toto.txt
) si on ne veut pas garder cette liste. L'idée des
filtres est d'envoyer directement la sortie de ls -l
vers
l'entrée de more
. Cela est réalisé avec l'opérateur
tube |
dans l'exemple qui précède.
UNIX comporte un grand nombre d'utilitaires (des filtres) que l'on peut associer de cette manière, de sorte qu'il est possible d'effectuer des opérations complexes par des traitements successifs à travers les filtres. À titre d'exemple, la liste des dix plus gros fichiers ou répertoires à l'intérieur du répertoire courant est obtenue par la chaîne
ordi:~ > du -sk *| sort -n -r | head
La commande du
affiche la taille des fichiers
(options -s
: sans rentrer dans les
répertoires, -k
: en kilo-octets), la transmet
à sort
qui la trie numériquement (-n
; sans
cette option, l'ordre alphabétique ferait apparaître 100 après 10 mais
avant 20...) et en ordre inversé (-r
), puis
finalement head
n'en garde que les dix premières lignes
et jette le reste. Utilisez la commande man
sur le
fonctionnement des filtres et pour plus d'information sur les options.