• Aucun résultat trouvé

Tri par adresse IP du fichier ”/etc/hosts”

17.2.1 Etude des fonctionnalit´ ´ es

Le fichier "hosts(5)" permet au syst`eme Unix d’associ´e une adresse r´eseau IP `a un ou plusieurs noms de machine.En se reportant au manuel du fichier "hosts(5)", le format utilis´e est le suivante :

{ Le fichier peut contenir des commentaires, tout caract`ere saisi apr`es le caract`ere "#" est ignor´e,

149

Chapitre 17. Programmation avanc´ee de Shell Scripts

{ Chaque ligne d´ecrivant l’association "adresse IP,noms de machine"

est compos´ee d’au moins deux champs s´epar´es par un ou plusieurs espaces ou tabulations. Le premier champ est l’adresse IP de la machine sous sa forme usuelle (format d´ecimal), le second est le nom officiel de la machine, c’est-`a-dire celui qui lui sera vraiment affect´e. Les autres champs, s´epar´es de la m^eme fa¸con sont les noms non-officiels, c’est-`a-dire une s´erie de noms qu’il sera possible d’utiliser pour la joindre.

Le probl`eme est donc de faire un tri num´erique sur les quatre champs de l’adresse IP (chacun ´etant s´epar´e par le caract`ere "." sachant que le s´eparateur de champ du fichier "hosts" est diff´erent et que les champs le constituant sont diff´erents. De plus, le caract`ere "." peut

^

etre utilis´e dans les noms de machines, en particulier lorsque les domaines Bind/DNS sont pr´ecis´es (cf. [8]).

17.2.2 M´ ethode utilis´ ee

Comme il l’a ´et´e explicit´e pr´ec´edemment, le probl`eme r´eside essentiellement dans les points suivants :

{ le s´eparateur de champ pour le fichier "hosts(5)" est diff´erent de celui qui pourrait nous servir pour faire le tri sur les champs de l’adresse IP,

{ le nom d’une machine, si son domaine est sp´ecifi´e, peut comporter un certain nombre de ".", lui-m^eme s´eparateur de champs pour l’adresse IP (cf [8]),

{ le tri doit ^etre effectu´e en num´erique uniquement sur les champs de l’adresse IP.

Il est clair, que la commande `a utiliser pour faire ce tri, est la commande "sort(1)". Par contre, nous devrons faire en sorte que l’entr´ee du tri comporte cinq champs :

{ le premier champ num´erique de l’adresse IP, { le second champ num´erique de l’adresse IP, { le troisi`eme champ num´erique de l’adresse IP, { le quatri`eme champ num´erique de l’adresse IP, { le ou les noms de la machine.

Il suffira alors de faire un tri num´erique sur les quatre premiers champs. Le r´esultat `a afficher devra reformatter de telle sorte qu’il ob´eisse au format du fichier "hosts(5)".

Nous aurons donc les ´etapes suivantes :

1. convertir le fichier "hosts(5)" de telle sorte que l’on dispose des cinq champs explicit´es pr´ec´edemment,

2. effectuer le tri,

3. reformatter le r´esultat du tri pour ob´eir au format usuel et l’afficher sur la sortie standard.

Or, un nom de machine peut utiliser le caract`ere "." afin d’identifier son domaine DNS. Par cons´equent, il faudra utiliser un autre caract`ere pour s´eparer

17.2. Tri par adresse IP du fichier ”/etc/hosts”

17.2.3 D´ eveloppement

Comme tout script Unix, le but est de n’utiliser, dans la mesure du possible, aucun fichier temporaire. Comme il l’a ´et´e d´evelopp´e au paragraphe pr´ec´edent, il est clair que les r´esultats s’enchainent les uns aux autres. Nous utiliserons donc les m´ecanismes de redirection d’entr´ee/sortie et des filtres.

Apr`es les commentaires d’ent^ete d’usage, la premi`ere chose `a faire est de reformatter le fichier "hosts(5)" pour l’envoyer `a la commande de tri "sort(1)". Pour cela, nous utiliserons la commande "sed(1)".

Celle-ci nous servira, dans un premier temps, `a supprimer les ´eventuels commentaires du fichier (pour plus de d´etails, cf. 15.4.3). Nous aurons donc :

sed -e ’/^#.*/d’ -e ’s/#.*$//’ /etc/hosts

Dans un deuxi`eme temps, la commande "sed(1)" va nous servir `a reformatter l’adresse IP, afin de substituer le caract`ere "." par le caract`ere

" :". Sachant que le format d’une telle adresse est compos´e de quatre nombres s´epar´es par ".", l’expression r´eguli`ere suivante la d´ecrit parfaitement :

[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*

Par cons´equent, toute ligne du fichier "host(5)" peut ^etre d´ecrite par l’expression suivante :

\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\(.*$\)

Ce qui nous permet d’avoir les r´ef´erences suivantes pour l’expression r´eguli`ere :

R´ef´erence Description

\1 Premier champ num´erique de l’adresse IP.

\2 Second champ num´erique de l’adresse IP.

\3 Troisi`eme champ num´erique de l’adresse IP.

\4 Quatri`eme champ num´erique de l’adresse IP.

\5 Noms de la machine.

Nous pourrons donc ´ecrire la requ^ete de substitution suivante :

s/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\(.*$\)/\1:\2:\3:\4:\5/

Ce qui nous donne :

sed -e ’/^#.*/d’ -e ’s/#.*$//’ /etc/hosts |\

sed -e \

’s/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\(.*$\)/\1:\2:\3:\4:\5/’

Il ne reste plus qu’`a effectuer le tri sachant que :

{ le tri doit s’effectuer par ordre num´erique croissant sur les quatre premiers champs,

{ chaque champ est s´epar´e par le caract`ere " :".

Nous obtenons :

S.Baudry, Introduction `a la programmation Bourne Shell – v4.0 151

Chapitre 17. Programmation avanc´ee de Shell Scripts

sed -e ’/^#.*/d’ -e ’s/#.*$//’ /etc/hosts |\

sed -e \

’s/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\(.*$\)/\1:\2:\3:\4:\5/’ |\

sort -t: +n

Il faut maintenant reformatter le r´esultat pour obtenir celui qui est conforme au fichier "hosts(5)". Nous allons ici utiliser lLa commande

"awk(1)". Celle-ci recevra donc des lignes (ou enregistrements) s´epar´es par le caract`ere " :" et devra effectuer le traitement suivant pour chacunes :

{ afficher le premier champ, { afficher le caract`ere ".", { afficher le second champ, { afficher le caract`ere ".", { afficher le troisi`eme champ, { afficher le caract`ere ".", { afficher le quatri`eme champ, { afficher le cinqui`eme ,

{ ins´erer un retour `a la ligne pour marquer la fin de l’enregistrement obtenu en r´esultat.

Nous avons donc : awk ’

BEGIN { FS=":" } {

printf ("%d.%d.%d.%d%s\n", ^$1, $2, $3, $4, $5) }

17.2.4 Programme obtenu

#!/bin/sh

#

# Description : Tri du fichier /etc/hosts par adresse IP

#

# Appel du programme : sorthost

#

# Fichiers externes : Non

#

printf ("%d.%d.%d.%d%s\n", ^$1, $2, $3, $4, $5) }