En ma qualité d'administrateur réseau (dit comme ça, ça en jette, hein?), je suis régulièrement amené à utiliser la commande « route » (bon, là, nettement moins).
Mon problème, c'est que quand la dite commande me renvoie une cinquantaine de routes dans le désordre, je peine un peu à m'y retrouver.
J'ai déjà appris que l'on pouvait trier efficacement une liste d'adresses IP, à l'aide d'un « sort -n -t. -k1,1 -k2,2 -k3,3 -k4,4».
C'est un premier pas.
Seulement la commande « route » commence par produire 2 lignes d'entête avant d'afficher le résultat.
Ces 2 lignes se retrouvent donc dans la moulinette de « sort » et l'affichage s'en retrouve perturbé (bon, OK, rien de désastreux, mais je suis un poil perfectionniste.)
Avec un brin d'imagination, j'ai tenté la mise en série de filtres dans un shell intermédiaire :
route | (head -n 2; sort -n -t. -k1,1 -k2,2 -k3,3)
Hélas, « head » bouffe bien plus que la tête, et « sort » n'a plus rien à se mettre sous la dent. Je ne récupère que les 2 lignes d'entête.
Même résultat en utilisant un « sed -e "n;q" » à la place du « head -n 2 ».
Il s'agit visiblement d'un problème de buffer d'entrée remplit trop avidement, puisque par exemple
ls -l /usr/bin | (head -n 1; cat)
me renvoie l'entête « total » suivie de la fin du « ls -l ».À noter que « ls -l /usr/bin | (dd of=/dev/null bs=8192 count=1; cat) » me renvoie exactement le même résultat (à l'exception de l'entête bien sûr); head utilise donc un buffer de 8 Ko.
Tout cela m'amène à une interrogation plus générale: comment appliquer efficacement plusieurs filtres sur la sortie d'une même commande, l'un sur les n premières lignes, et un autre sur la suite ?
L'idée de la mise en série dans un shell tient pourtant la route, puisque par exemple
route | (read a; read b; echo -e "$a\n$b"; sort -n -t. -k1,1 -k2,2 -k3,3)
fonctionne.Faut-il considérer que head, sed, et probablement d'autres sont buggés?
Ces commandes sont-elles sensées absorber plus de données qu'elles ne vont finalement en traiter?
Y aurait-il un ajustement possible quelque part pour éviter cela?
Ou peut-être que j'en demande trop à un simple shell et que ferais mieux de faire du <votre langage de script préféré> ?
Vos commentaires et avis sur la question sont les bienvenus.
# et si tu faisais
Posté par Tgnard . Évalué à 3.
[^] # Re: et si tu faisais
Posté par Nicolas Melay . Évalué à 1.
Ma commande est un exemple.
Dans ce cas très précis je pourrais aussi réafficher les entêtes à la main, etc.
Mais tout l'intérêt est dans le problème.
[^] # Re: et si tu faisais
Posté par LaBienPensanceMaTuer . Évalué à 1.
genre:
[gco@gc]:~% plop=`/sbin/route -n` ; nplop=`echo $plop |wc -l` ; echo $plop |head -n2 ; echo $plop |tail -n$((nplop-2)) | sort -n -t. -k1,1 -k2,2 -k3,3
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.1.1.254 0.0.0.0 UG 0 0 0 eth0
10.1.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
[^] # Re: et si tu faisais
Posté par Nicolas Melay . Évalué à 1.
Je préfère quand même traiter la sortie en un seul flux.
Voir ma ligne de commande avec les « read ».
[^] # Re: et si tu faisais
Posté par JereMe . Évalué à 1.
cf mon commentaire plus loin sur pourquoi ca marche 'en caractères'. Après, je sais pas si y a toujours autant de caractères. Mais bon, je sais pas pourquoi il y aurait toujours 2 lignes aussi.
[^] # Re: et si tu faisais
Posté par Nicolas Melay . Évalué à 1.
Ça reste difficilement portable vers d'autres systèmes, d'autres locales, etc.
[^] # Re: et si tu faisais
Posté par a_jr . Évalué à 0.
Mais un administrateur reseau a-t-il vraiment besoin de cela ? Si c'etait le cas, cet option n'existerait-elle pas deja, depuis le temps que la commande route existe ?
A moins qu'il ne s'agisse d'un programme de presentation des routes, mais dans ce cas, mieux vaut prendre un langage plus evolue, un langage d'admin, comme le perl, non ?
Le bonjour chez vous,
Yves
# Commande ip
Posté par Bibinsa . Évalué à 2.
ip route (ou ip r pour aller plus vite) permet, de base, un affichage plus clair
Package iproute.
[^] # Re: Commande ip
Posté par Nicolas Melay . Évalué à 1.
[^] # Re: Commande ip
Posté par Nicolas Melay . Évalué à 1.
# Euh...
Posté par Hojo . Évalué à 2.
Et d'ailleurs je ne comprends pas trop l'utilité du tout ce que cela fait, c'est retourner les 2 premières lignes de la sortie standard (qui sont ensuite traitées par le sort...)
[^] # Re: Euh...
Posté par sk . Évalué à 1.
ca ne marche pas ?
Concernant le coup du head -n 2, je vois pas vraiment où head serait buggé, vu qu'il fait exactement ce que tu lui demandes, cad afficher uniquement les deux premières lignes...
[^] # Re: Euh...
Posté par Nicolas Melay . Évalué à 1.
1) les deux premières lignes telles quelles, et
2) les lignes suivantes, triées.
[^] # Re: Euh...
Posté par Nicolas Melay . Évalué à 1.
Ne pas oublier que sort ne traite que les données qui n'ont pas été traitées par sed.
Hors sed utilise un buffer de 4 Ko, largement de quoi contenir toutes mes routes.
Donc sed supprime les 2 lignes et resort la suite telle quelle.
Et la 2ème non plus, car mon objectif est de conserver les entêtes, pas de les éliminer.
Ce que je cherche à faire avec le head, c'est lire les 2 premières lignes (et uniquement les 2 premières) et les afficher, pour ensuite ne laisser à sort que les données, hors entêtes.
[^] # Re: Euh...
Posté par Benjamin (site web personnel) . Évalué à 2.
donc tu n'es pas administrateur système d'opérateur sous AS ?
et donc j'aurais rapidement un problème :
benjamin@gibu:~$ route -n |wc -l
# quelques instants plus tard ...
182287
à mon avis, dès que je vais en extraire des bouts, ca ne tiendra pas dans 4Ko hein ;)
# C'est pas un bug, c'est une fonctionnalité (mal comprise?)
Posté par JereMe . Évalué à 2.
Oui. Sinon, sans connaitre la taille des lignes, tu vas sinon faire une lecture (appel système) par caractères et vive l'efficacité.
head n'a jamais été une commande qui avale des lignes et laisse inchanger le reste. Il faut considerer qu'il prend tout et ne rend que les -n lignes demandé. Dans le cas d'un long ls -l /usr/bin , c'est juste que le programme quitte et s'amuse pas à lire inutilement ce qui reste, ce qui pourrait prendre du temps pour rien.
[^] # Re: C'est pas un bug, c'est une fonctionnalité (mal comprise?)
Posté par Nicolas Melay . Évalué à 1.
Je ne connais pas bien la libc, mais un truc du genre « lire le flux f dans le buffer b jusqu'à ce qu'on rencontre le caractère c » c'est pas possible ?
[^] # Re: C'est pas un bug, c'est une fonctionnalité (mal comprise?)
Posté par Pascal . Évalué à 2.
int i=0;
while(read(0,b+i++,1)>0)
{
if(b[i-1]==c)
break;
}
[^] # Re: C'est pas un bug, c'est une fonctionnalité (mal comprise?)
Posté par Nicolas Melay . Évalué à 1.
Je faisais plutôt allusion à fgets/getline.
[^] # Re: C'est pas un bug, c'est une fonctionnalité (mal comprise?)
Posté par JereMe . Évalué à 2.
fgets/getline sont des fonctions de la libc. Tu as deux niveaux de bufferisations (système et libc).
Ces fonctions lisent un buffer de taille x avec l'appel système read et stocke "en interne" ce buffer.
fgets et getline te renvoie qu'une ligne, mais tout un buffer a été lu en interne de la libc. Donc le problème ne change pas avec ces fonctions.
# tee + pipes nommés
Posté par Hardy Damien . Évalué à 3.
P.e. en utilisant tee (qui balance la sortie sur plusieurs fichiers) et utiliser des pipes nommés à la place des fichiers pour récupérer les 2 première lignes et par ailleurs le reste trié ...
Dam
[^] # Re: tee + pipes nommés
Posté par Nicolas Melay . Évalué à 0.
Non ça ne marche pas.
Deux cas de figure :
1) head dans le pipe nommé
La sortie du pipe nommé arrive sur la sortie standard après la sortie de la commande principale.
Enfin en clair, route | tee >(head -n 2) | tail +3 ne fonctionne pas, les lignes d'entêtes apparaissent en fin de commande.
Et il ne s'agit pas juste d'un problème de timing, route | tee >(head -n 2) | (sleep 5; tail +3) donne le même résultat (mais 5 secondes plus tard ;)).
2) tail dans le pipe nommé
Dans l'autre sens, route | tee >(tail +3) | head -n 2 ne me renvoie que les entêtes.
Le head s'applique en fait à la sortie des 2 commandes.
Je ne suis pas 100% sûr de mon interprétation du résultat, mais enfin ce qui est certain c'est que ça ne fonctionne pas.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.