mardi 9 novembre 2010

Les secrets de cat

La commande cat copie vers la sortie standard le contenu du ou des fichiers indiqués sur la ligne de commande. Une simple redirection permet donc d'obtenir un fichier qui est la concaténation de plusieurs fichiers:

toto@rigel:~/test$ cat garçons
Toto
Riri
toto@rigel:~/test$ cat filles
Tata
Titine
toto@rigel:~/test$ cat garçons filles > toutlemonde
toto@rigel:~/test$ cat toutlemonde
Toto
Riri
Tata
Titine
toto@rigel:~/test$

C'est la finalité première de cat comme d'ailleurs annoncé au début de la page man:

cat - concatenate files and print on the standard output

Si aucun fichier n'est indiqué sur la ligne de commande, cat copie alors l'entrée standard vers la sortie standard:

cat est en attente de ce que nous allons saisir au clavier (entrée standard) pour l'envoyer vers la sortie standard.
Nous saisissons "hello"


et tapons sur Enter pour envoyer le texte saisi vers cat:

A l'écran figure ce que nous avons tapé au clavier, mais aussi ce qui a été renvoyé par cat via stdout (c'est évidement le même texte). cat continue à attendre la suite.
Nous interrompons le flux d'entrée par appui sur CTRL-D.
On peut s'amuser de la même façon avec tr par exemple:



Seul un appui sur Enter sépare les deux dernières copies d'écran.
Ce genre de manipulation est d'une utilité toute relative sauf si nous redirigeons stdout nous donnant ainsi la possibilité de créer un petit fichier texte:

Cette fois évidemment les lignes n'apparaissent pas en double puisque l'output se fait vers le fichier salut. Comme précédemment, indiquons à cat avec CTRL-D qu'il ne doit plus rien attendre et puis vérifions (avec cat toujours) que le fichier salut contient bien ce qu'il est censé contenir.


On peut intercaler la lecture de stdin entre la lecture de plusieurs fichiers en utilisant le signe "-":


cat a lu le premier fichier, envoyé son contenu dans toutlemonde et est en attente de la suite qui doit venir de stdin. Saisissons "++++++", puis appuyons sur Enter:


"++++++" se trouve déjà dans toutlemonde. Il reste à appuyer sur CTRL-D pour terminer:


Attention, il s'agit de terminer proprement et non pas en utilisant CTRL-C, faute de quoi cat ne lira pas le second fichier.

Considérons maintenant cette commande:


Aucun nom de fichier n'est indiqué, donc cat devrait lire l'entrée standard. Mais l'instruction de redirection << FIN signifie à bash que ce qui suit, donc ici ce qui sera écrit à l'écran, constituera le flux d'entrée et ce jusqu'au mot FIN. cat va donc lire non pas l'entrée standard, mais le contenu de l'écran jusqu'à la rencontre du délimiteur FIN:




Un simple appui sur Enter sépare ces deux copies d'écran.
Le texte

hello
ola
hi

est ce qui s'appelle un here document.

L'emploi de here documents est surtout utile dans les scripts: il permet d'éviter la multiplication des commandes echo.
Soit le script courses:

#!/bin/bash

echo
echo Bonjour $USER

cat  << COURSES

Voici la liste des courses:

Riz
Grains
Saucisses
Tomates
Piments verts

echo 1
COURSES

echo 2

Voici ce que donne son exécution:


Nous avons volontairement, pour des raisons pédagogiques, pollué le script avec "echo 1" et "echo 2".
"echo 1" est lu par cat et ensuite renvoyé vers stdout.
"echo 2" est une commande qui est exécutée.