La plupart du travail en ligne de commande s'applique à des fichiers. Dans cette section nous allons voir comment surveiller et filtrer l'information dans les fichiers, extraire des informations spécifiques avec une simple commande, et trier des fichiers
Ces commandes ont pratiquement toutes la même syntaxe :
commande [option(s)] [fichier(s)] |
et peuvent être utilisées dans un tube. Toutes sont utilisées pour imprimer une partie d'un fichier selon certains critères.
L'utilitaire cat agglomère des fichiers et les imprime sur la sortie standard. c'est une des commandes les plus utilisées. Vous pouvez utiliser :
# cat /var/log/mail/info |
pour afficher, par exemple, le contenu du journal (log) du démon de courrier sur la sortie standard[15]. la commande cat a une option très utile (-n) qui permet de numéroter les lignes affichées.
Certains fichiers, comme les fichiers journaux des démons (s'ils sont utilisés) sont souvent de taille énorme[16] et les afficher dans leur intégralité à l'écran n'a aucun intérêt. Vous voudrez souvent ne consulter qu'une partie d'un fichier. Vous pouvez par exemple utiliser la commande tail pour n'afficher que les dernières lignes. Ainsi, la commande :
# tail /var/log/mail/info |
affichera les dix dernières lignes du fichier /var/log/mail/info. Si vous souhaitez n'afficher que les deux premières lignes vous pouvez utiliser l'option -n :
# head -n2 /var/log/mail/info |
La commande head est similaire à tail, mais affiche les premières lignes d'un fichier. Cette commande sans options :
# head /var/log/mail/info |
affiche les 10 premières lignes de /var/log/mail/info. Comme avec head vous pouvez imprimer les deux dernières lignes à l'aide de l'option -n :
# head -n2 /var/log/mail/info |
Vous pouvez aussi utiliser ces commandes de concert. Par exemple, si vous souhaitez seulement afficher les lignes 9 et 10, vous pouvez lancer :
# head /var/log/mail/info | tail -n2 |
où la commande head sélectionne les 10 premières lignes du fichier, les passe à la commande tail au travers d'un tube (|) qui n'en retourne que les deux dernières lignes. De la même façon vous pouvez sélectionner toutes les lignes à partir de la ligne 20 :
# tail -n20 /var/log/mail/info |head -n1 |
Nous disons ici à tail de sélectionner les 20 dernières lignes du fichier, puis de les passer à head. Cette dernière en imprime alors la première ligne.
Supposons maintenant que nous souhaitions à la fois afficher à l'écran et enregistrer le résultat de la commande précédente dans le fichier resultats.txt. L'utilitaire tee va nous y aider. Sa syntaxe est :
tee [option(s)] [file] |
Nous changeons alors la commande précédente :
# tail -n20 /var/log/mail/info |head -n1|tee resultats.txt |
Encore un exemple. Nous voulons sélectionner les 20 dernières lignes, les enregistrer dans resultats.txt, mais imprimer à l'écran seulement les premières de ces lignes. Nous écrivons alors :
# tail -n20 /var/log/mail/info |tee resultats.txt |head -n1 |
La commande tee a une option très utile (-a) qui permet d'ajouter les informations reçues à un fichier existant au lieu de l'écraser.
Revenons à la commande tail. Les fichiers comme les journaux changent souvent car les démons y rajoutent sans cesse de l'information sur leur activité. Si vous voulez alors surveiller de manière interactive des changements sur ces journaux, vous pouvez tirer avantage de l'une des options les plus utiles de tail : -f:
# tail -f /var/log/mail/info |
Dans ce cas, tous les changements dans le fichier /var/log/mail/info sont affichés immédiatement à l'écran. Cette option est très utile pour surveiller l'activité de votre système. Par exemple, en regardant dans le journal /var/log/messages, vous pouvez surveiller les messages du système et plusieurs démons. Cette option peut aussi être utiliser pour surveiller n'importe quel autre fichier.
Dans la section qui suit nous allons voir comment nous pouvons utiliser grep comme filtre pour séparer les messages de Postfix des messages émanant des autres services.
D'accord, le nom n'est pas intuitif mais son utilisation est très simple : il cherche un motif donné en argument dans un ou plusieurs fichiers. Sa syntaxe est :
grep [options] <motif> [un ou plusieurs fichier(s)] |
Si on a précisé plusieurs noms de fichiers, ceux-ci apparaîtront en début des lignes et rempliront les critères du motif, à moins qu'on ait utilisé l'option -h. L'option -l, quant à elle, a pour effet de n'afficher que le nom des fichiers dont au moins une ligne remplit les conditions du motif. Le motif est une expression régulière, bien que la plupart du temps il ne consiste qu'en un simple mot. Les options les plus couramment utilisées sont les suivantes :
-i : rechercher en ignorant la casse (c'est-à-dire ignorer la différence entre majuscules et minuscules).
-v : inverser la recherche, donc trouver les lignes ne correspondant pas au motif.
-w : dit à grep que le motif doit correspondre à un mot entier. Attention, les caractères considérés comme pouvant faire partie d'un mot dépendent du réglage de la langue.
Reprenons notre exemple du fichier journal du démon de courrier. Nous souhaitons trouver toutes les lignes du fichier /var/log/mail/info qui contiennent la séquence «postfix» :
# grep postfix /var/log/mail/info |
La commande grep peut être utilisée dans un tube. Nous pouvons ainsi obtenir le même résultat en faisant :
# cat /var/log/mail/info | grep postfix |
Si nous voulons inverser la condition pour sélectionner les lignes qui ne contiennent pas la séquence «postfix», nous utilisons l'option -v :
# grep -v postfix /var/log/mail/info |
Supposons que nous voulions trouver tous les messages signalant un message envoyé avec succès. Dans ce cas, nous devons filtrer les lignes du journal provenant du démon de courrier (contenant donc la séquence «postfix») contenant la séquence indiquant un envoi réussi («status=sent») :
# grep postfix /var/log/mail/info |grep status=sent |
Dans ce cas, grep est utilisé deux fois. C'est possible mais pas très élégant. Nous pouvons obtenir le même résultat en utilisant l'utilitaire fgrep. Pour cela nous devons créer le fichier sequences.txt contenant les séquences écrites sur une colonne. Un tel fichier peut être obtenu de cette façon :
# echo -e 'status=sent\npostfix' >./sequences.txt |
Nous appelons alors une commande utilisant le fichier de séquences sequences.txt et l'utilitaire fgrep au lieu du double appel à grep :
# fgrep -f ./sequences.txt /var/log/mail/info |
le fichier ./sequences.txt peut contenir autant de séquences de filtrage que vous le souhaitez. Chacune d'elles doit se trouver sur une nouvelle ligne. Par exemple, pour sélectionner les messages correctement envoyés à pierre@mandrakesoft.com, il suffira de rajouter cette adresse dans notre fichier ./sequences.txt :
# echo 'pierre@mandrakesoft.com' >>./sequences.txt |
et relancer la commande précédente.
Il est évident que vous pouvez combiner grep avec tail et head. Si nous souhaitons trouver l'avant-dernier message envoyé à Pierre, nous tapons :
# fgrep -f ./sequences.txt /var/log/mail/info | tail -n2 | head -n1 |
Nous appliquons ici le filtre construit précédemment et dirigeons le résultat dans un tube pour les commandes tail et head. Elles se chargent de sélectionner l'avant-dernière ligne des données reçues.
la commande wc (Word Count : compteur de mots) est utilisée pour compter le nombre de lignes et de mots d'un fichier. Elle peut aussi servir à compter le nombre d'octets, de caractères, et la longueur de la ligne la plus longue. Sa syntaxe est :
wc [option(s)] [fichier(s)] |
Les options suivantes sont particulièrement utiles :
la commande wc affiche par défaut le nombre de lignes, mots et caractères du fichier fourni. Voici quelques exemples :
Si nous souhaitons connaître le nombre d'utilisateurs sur notre système, nous pouvons taper :
$wc -l /etc/passwd |
Si nous souhaitons connaître le nombre de processeurs sur notre système :
$grep "model name" /proc/cpuinfo |wc -l |
Dans la section précédente nous avons obtenu une liste de messages correspondant aux séquences du fichier ./sequences.txt. Si nous souhaitons connaître le nombre de ces messages, nous pouvons rediriger les résultats de notre filtre dans un tube pour la commande wc :
# fgrep -f ./sequences.txt /var/log/mail/info | wc -l |
Voici la syntaxe de cet utilitaire de tri très puissant[17]:
sort [option(s)] [fichier(s)] |
Considérons le tri du fichier /etc/passwd. Comme vous pouvez le voir :
$ cat /etc/passwd |
le fichier /etc/passwd n'est pas trié. Nous voulons le trier par champ login (nom d'utilisateur) :
$ sort /etc/passwd |
La commande sort trie les données par ordre croissant sur le premier champ (dans notre cas, le login) par défaut. Si nous voulons trier les données par ordre décroissant il faut utiliser l'option -r :
$ sort -r /etc/passwd |
Chaque utilisateur a son propre UID (identifiant numérique de l'utilisateur) écrit dans le fichier /etc/passwd. Trions donc les utilisateurs selon leur UID :
$ sort /etc/passwd -t":" -k3 -n |
Nous avons utilisé ici les options suivantes de sort :
$ sort /etc/passwd -t":" -k3 -n -r |
Notez bien ces deux options importantes de sort :
Enfin, si nous voulons trouver l'utilisateur ayant l'identifiant UID le plus élevé :
$ sort /etc/passwd -t":" -k3 -n |tail -n1 |
Nous trions le fichier /etc/passwd par ordre d'UID ascendant, et redirigeons le résultat sur un tube pour la commande tail qui ne laisse passer que la première ligne.
[15] Certains exemples de cette section sont basés sur des tâches réelles avec des fichiers journaux de certains services. Assurez-vous que le démon syslogd soit lancé (il permet aux autres démons d'écrire leurs journaux), ainsi que le démon dont il est question (ici Postfix) et que vous travaillez en tant que root. Vous pouvez quoi qu'il en soit toujours appliquer les exemples à d'autres fichiers.
[16] Par exemple, le fichier /var/log/mail/info enregistre toutes les informations à propos des messages envoyés, messages rapatriés par les utilisateurs avec le protocole POP, etc.
[17] Nous ne parlons que brièvement de sort ici car des livres entiers pourraient être écrits sur le sujet.