less est lent si $LESSOPEN existe

Le
Rémi Moyen
Bonjour,

J'ai un comportement un peu bizarre avec 'less'. À chaque fois que je
l'invoque, il ne se passe rien pendant environ 5 secondes avant de
m'afficher le fichier (plus aucun problème après). Par défaut, mon
environnement contient LESSOPEN = "|/usr/bin/lesspipe.sh %s" et je me
suis dit que ça venait peut-être de là.

En effet, si je supprime la variable LESSOPEN, less réagit
instantanément. Mais j'ai regardé le script lesspipe.sh en question,
il est tout simple, et surtout, si je le remplace par un script vide
(avec juste une ligne #!/bin/sh -), c'est toujours aussi lent. Pire
encore, si je fais, par exemple, LESSOPEN = "|/bin/bash -c ''" cad que
j'invoque un bash (/bin/sh est aliasé sur /bin/bash, chez moi) et
c'est tout, j'ai le même délai d'environ 5 secondes. Si je lance un
bash (ou lesspipe.sh, d'ailleurs) directement en ligne de commande,
j'ai le résultat instantanément, donc c'est bien lié spécifiquement=
à
less.

Donc j'ai l'impression que le simple fait d'invoquer un pipe pour less
cause ce délai, quelque soit le contenu du fichier qui est dans
LESSOPEN

Est-ce que quelqu'un a déjà vu ce genre de choses ou a une idée de
comment faire ?

Dans l'immédiat, j'ai enlevé LESSOPEN, parce que j'en ai pas vraiment
l'usage, mais c'est une fonctionnalité agréable que j'aimerais pouvoir
garder

Merci d'avance !
--
Rémi Moyen
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Nicolas George
Le #16540061
Rémi Moyen wrote in message
Est-ce que quelqu'un a déjà vu ce genre de choses ou a une idée de
comment faire ?



Deux tests à faire :

time less un_fichier

et taper immédiatement q : ça dira si le temps perdu est passé en CPU ou en
attente.

strace -ftto /tmp/less less un_fichier

Et regarder où part le temps.
Rémi Moyen
Le #16540611
On Aug 13, 5:28 pm, Nicolas George
Deux tests à faire :

time less un_fichier

et taper immédiatement q : ça dira si le temps perdu est passé en CPU ou en
attente.



% time less toto
sum 0.266 0.638 0:14.92 5.9% 0

Je suis sous csh avec $time sum %U %S %E %P %W, donc c'est 0.266 en
user, 0.638 en kernel, pour un temps total de 14.92. En d'autres
termes, il passe son temps à dormir...

strace -ftto /tmp/less less un_fichier

Et regarder où part le temps.



Hmmm... Rien de flagrant ici. Je peux envoyer le log si ça amuse
quelqu'un, mais je ne vois pas d'opération qui soit spécifiquement
longue. Il semble essayer d'ouvrir de très nombreuses fois des
fichiers qui n'existent pas, avec des lignes du genre :
open("/usr/X11R6/lib64/tls/x86_64/libpcre.so.0", O_RDONLY) = -1 ENOENT
(No such file or directory)
stat("/usr/X11R6/lib64/tls/x86_64", 0x7fbfffc680) = -1 ENOENT (No such
file or directory)

Et aussi j'ai des dizaines de groupes de paquets de plusieurs
centaines de lignes (à vue d'oeil) de :
fstat(103, 0x7fbffe3290) = -1 EBADF (Bad file descriptor)

Tout ça se situe après le début de l'utilisation de $LESSOPEN, je
suppose, puisque j'ai dans la première seconde du log :
26335 18:06:38.914991 execve("/bin/csh", ["/bin/csh", "-c", "/usr/bin/
lesspipe.sh toto"], [/* 252 vars */]) = 0

Il lui faut déjà 5 secondes pour en arriver à :
26335 18:06:43.897994 stat("/usr/bin/lesspipe.sh", {st_mode=S_IFREG|
0755, st_size63, ...}) = 0
26335 18:06:43.898103 access("/usr/bin/lesspipe.sh", X_OK) = 0

Puis il perd encore 20 secondes avant de faire :
26507 18:07:01.104560 execve("/usr/bin/lesspipe.sh", ["/usr/bin/
lesspipe.sh", "toto"], [/* 252 vars */]) = 0

Ensuite, les choses vont plus vite :
26507 18:07:01.153357 open("/usr/bin/lesspipe.sh", O_RDONLY) = 3

(et le log finit -- donc less s'est vraiment lancé -- vers
18:07:02.15)

Mais à part ça...
--
Rémi Moyen
Nicolas George
Le #16540601
Rémi Moyen wrote in message
Je suis sous csh



(Une petite question en passant : pourquoi restes-tu avec cette bouze ?)

Hmmm... Rien de flagrant ici. Je peux envoyer le log si ça amuse
quelqu'un, mais je ne vois pas d'opération qui soit spécifiquement
longue.



Puisque le temps est passé essentiellement à dormir, ça doit se voir dans
les timestamps. Au pire, tu traces le graphique dans gnuplot pour voir où
est-ce qu'il y a des trous.
Vincent Lefevre
Le #16542891
Dans l'article Rémi Moyen
En d'autres termes, il passe son temps à dormir...



Chez moi, en temps normal, lesspipe est très rapide (immédiat). Mais
sous Mac OS X, quand il y a beaucoup d'accès disque, lesspipe devient
très lent (jusqu'à plusieurs dizaines de secondes). Je pense alors
qu'il doit passer son temps à attendre les données du disque. Un
script Perl serait probablement plus efficace.

Hmmm... Rien de flagrant ici. Je peux envoyer le log si ça amuse
quelqu'un, mais je ne vois pas d'opération qui soit spécifiquement
longue. Il semble essayer d'ouvrir de très nombreuses fois des
fichiers qui n'existent pas, avec des lignes du genre :
open("/usr/X11R6/lib64/tls/x86_64/libpcre.so.0", O_RDONLY) = -1 ENOENT
(No such file or directory)
stat("/usr/X11R6/lib64/tls/x86_64", 0x7fbfffc680) = -1 ENOENT (No such
file or directory)



Oui, c'est un script shell, donc ça lance plein de trucs. Sous
certaines conditions, c'est inefficace.

Et aussi j'ai des dizaines de groupes de paquets de plusieurs
centaines de lignes (à vue d'oeil) de :
fstat(103, 0x7fbffe3290) = -1 EBADF (Bad file descriptor)



Je n'ai qu'un seul groupe de EBADF ici. C'est zsh qui le génère.
Cela se voit aussi sur:

strace -f -r -o strace.out zsh -fc true

Ces lignes EBADF occupent une majeure partie du fichier strace.out.
Mais ce n'est pas ça qui prend du temps.

Tu peux utiliser l'option -r de strace (comme je l'ai fait ci-dessus)
pour obtenir les temps entre deux appels système; cela est souvent
plus utile que l'heure absolue.

--
Vincent Lefèvre 100% accessible validated (X)HTML - Blog: Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
telenligne t-online
Le #16545121
Rémi Moyen wrote:

lesspipe.sh toto"], [/* 252 vars */]) = 0

Il lui faut déjà 5 secondes pour en arriver à :



Bah, il te manque encore quelque millions de variables.
Et n'oublie pas de rajouter aussi quelque million de repertoires
dans le path et les LD_path.

ca permet d'avoir un env super top de la mort qui tue qui t'evite
d'avoir a setter a la mimine les variable specific de chaque applie
avant que tu l'utilise.

Ajoute aussi un bon millier de repertoires en automount, ca vaut
bien quelque million de repertoire en local.

Je conseille aussi a ta societe qui t'impose csh, d'imposer que
chaque script que tu doive ecrire, appelle sucessivement
bash -> csh -> zsh et ensuite ash . C'est pour aider la machine
a bien connaitre chaque langage shell, et a force de s'entrainner
a traduire les env et a parler different shell, elle finira par
les connaitre par coeur et ira biensure, bien plus vite.


En periode de JO, il ne faut pas negliger l'entrainnement
des machines
Rémi Moyen
Le #16544741
On Aug 13, 6:18 pm, Nicolas George
> Je suis sous csh

(Une petite question en passant : pourquoi restes-tu avec cette bouze  ?)



Parce que c'est le shell officiel utilisé par tout le monde dans ma
boîte. Je pourrais en utiliser un autre (et en fait, j'aimerais
bien !), mais dans ce cas je ne pourrais plus utiliser directement les
mêmes fichiers de configs que tout le monde, et je ne pourrais pas
faire profiter les autres des modifs que je fais, et je serais perdu
quand je vais aider quelqu'un sur sa machine et vice-versa. En un mot,
c'est le standard imposé et c'est comme ça, même si ça ne me plait
pas...

> Hmmm... Rien de flagrant ici. Je peux envoyer le log si ça amuse
> quelqu'un, mais je ne vois pas d'opération qui soit spécifiquement
> longue.

Puisque le temps est passé essentiellement à dormir, ça doit se voi r dans
les timestamps. Au pire, tu traces le graphique dans gnuplot pour voir o ù
est-ce qu'il y a des trous.



Ben j'arrive vraiment pas à voir de trou notable dans les timestamps.
J'ai pas fait de graph, mais j'ai compté combien de lignes dans mon
log par seconde d'execution. Sur la vingtaine de secondes que dure le
log, j'en ai certes 5 ou 6 où j'ai moins de 1000 lignes contre
2000-5000 en moyenne pour les autres, mais je ne vois pas de "trou"
clair même dans ces quelques secondes-là (et c'est pas juste ces
quelques secondes qui ralentissent mon less à ce point-là, ça ne
représente qu'à peine un quart du temps d'excution total). J'ai
l'impression que certains close() correspondant (enfin, je pense) à
des fichiers qui sont sur un disque NFS sont relativement longs, mais
ça ne me paraît pas énorme et à part ça, je ne vois rien de suspe ct...
J'ai essayé aussi avec -r comme suggéré par Vincent Lefevre, mais
c'est pas plus clair. Sans doute que je n'arrive pas à lire le log
correctement ?
--
Rémi Moyen
Rémi Moyen
Le #16544951
On Aug 14, 2:01 am, Vincent Lefevre
Oui, c'est un script shell, donc ça lance plein de trucs. Sous
certaines conditions, c'est inefficace.



Tiens, c'est vrai que quand je lance une nouvelle console, il faut
bien 10 secondes avant que j'ai le prompt, sans doute à cause de 40
000 fichiers de configs dans tous les sens. Du coup, je me suis
demandé si ça ne pourrait pas être ça. Donc j'ai fait un programme C
plus que minimaliste ("int main(int argc, char** argv) {return 0;}")
que j'ai mis dans LESSOPEN. Ben le résultat est le même, cad que less
est long. Peut-être un petit peu moins qu'avant (genre 15 secondes au
lieu de 20), mais c'est pas vraiment mieux.

Il semblerait ceci dit qu'un shell soit invoqué dans tous les cas (ce
qui est assez logique si il utilise réellement un pipe pour
communiquer entre LESSOPEN et less -- mais le résultat est le même si
je mets LESSOPEN="/tmp/lesspipe %s", i.e. sans le pipe), même si aprè s
dans LESSOPEN c'est pas un script shell. Par exemple, j'ai dès le
début :
execve("/bin/sh", ["sh", "-c", "/bin/csh -c /tmp/lesspipe\ toto"...],
[/* 252 vars */]) = 0
Et l'execution du programme en lui-même :
execve("/tmp/lesspipe", ["/tmp/lesspipe", "toto"], [/* 252 vars */]) =
0
commence elle tout à la fin du log, moins d'une seconde avant la fin.

En d'autres termes et si j'ai bien compris, il doit lancer un shell
qui lui-même lance le programme qui est dans LESSOPEN. C'est
l'ouverture du shell qui prend du temps, ce qui explique que je puisse
mettre n'importe quoi dans LESSOPEN sans que ça influe sur le
résultat.

Bon, maintenant, est-ce qu'il y a un moyen de lui dire de lancer ce
shell sans sourcer tous les fichiers d'environnement (genre .cshrc et
autres) ? C'est probablement ça qui fait que c'est long, et c'est une
partie que je ne peux pas/ne veux pas modifier. Y'a bien les options
qu'il faut pour bash ou csh, mais comment faire pour que ces options
soient passées au shell qui est lancé pour invoquer le programme qui
est dans LESSOPEN ? Je ne vois rien là-dessus dans le man de less.

Tu peux utiliser l'option -r de strace (comme je l'ai fait ci-dessus)
pour obtenir les temps entre deux appels système; cela est souvent
plus utile que l'heure absolue.



Ah oui, c'est pas mal aussi.

Merci quand même de ton aide !
--
Rémi Moyen
Jean-Marc Bourguet
Le #16545111
Rémi Moyen
Tiens, c'est vrai que quand je lance une nouvelle console, il faut
bien 10 secondes avant que j'ai le prompt, sans doute à cause de 40
000 fichiers de configs dans tous les sens.



Il y a moyen de ne pas exécuter des choses qui n'ont pas de sens (tester
prompt par exemple pour savoir si c'est un shell interactif et donc ne pas
setter les alias si ce n'est pas le cas)... Je suis plus ou moins dans la
même situation que toi au boulot -- csh quasi imposé comme shell interactif
(j'ai quand même hacké un peu pour avoir tcsh) -- et j'ai un squelette avec
les différents cas. J'essaie de le poster ici lundi ou mardi. Si je ne le
fait pas et que tu n'as pas résolu le problème, recontacte moi directement.

A+

--
Jean-Marc
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Rémi Moyen
Le #16545921
On Aug 14, 12:14 pm, Jean-Marc Bourguet
Rémi Moyen > Tiens, c'est vrai que quand je lance une nouvelle console, il faut
> bien 10 secondes avant que j'ai le prompt, sans doute à cause de 40
> 000 fichiers de configs dans tous les sens.



Ce qui est bien à l'origine de mon problème, d'ailleurs, je confirme :
Si je supprime mon .cshrc, less met 1 à 2 secondes pour se lancer, à
peine plus que si je ne définis pas LESSOPEN.

Il y a moyen de ne pas exécuter des choses qui n'ont pas de sens (teste r
prompt par exemple pour savoir si c'est un shell interactif et donc ne pa s
setter les alias si ce n'est pas le cas)...



J'aimerais bien, mais je ne vois pas trop comment faire. Ce qui me
gêne, c'est que la configuration standard est d'avoir son .cshrc qui
est un lien vers le cshrc "officiel" (quelque part sur un disque
réseau), qui fait des tonnes de choses et ensuite source un .mycshrc
(si il existe) pour les réglages personnels que chacun fait. Le
problème, c'est que l'IT considère qu'ils peuvent changer le .cshrc
dans le $HOME d'un user (cad le lien symbolique) sans avertissement --
ils l'ont déjà fait, quand une migration des disques s'est accompagné e
d'un renommage de tous les points de montages NFS.

Du coup, j'aurais bien mis dans mon .cshrc une batterie de tests avant
d'appeler le cshrc global uniquement quand il faut (et de garder
mon .mycshrc pour paufiner ensuite), mais si je fais ça je n'ai aucune
garantie que mon .cshrc ne va pas disparaître la prochaine fois que
l'IT fera une mise à jour. Évidemment, je peux prendre le risque (avec
un backup à côté, le risque est juste de devoir ré-installer mon tr uc
une fois de temps en temps) ou aller râler auprès des ingénieurs
systèmes, mais bon, j'aimerais mieux trouver une solution qui rentre
dans les contraintes actuelles.

Je suis plus ou moins dans la
même situation que toi au boulot -- csh quasi imposé comme shell inte ractif
(j'ai quand même hacké un peu pour avoir tcsh) -- et j'ai un squelett e avec
les différents cas.  J'essaie de le poster ici lundi ou mardi.  Si je ne le
fait pas et que tu n'as pas résolu le problème, recontacte moi direct ement.



Ah oui, je veux bien, merci d'avance !

J'avais déjà un truc pour utiliser un tcsh, que tu m'avais indiqué il
y a quelques temps (ici :
http://groups.google.com/group/fr.comp.os.unix/browse_frm/thread/dc15fae77d be5eec/b1a48f6da32b7656),
mais ça ne marche plus depuis quelques jours et un changement majeur
des configs. Je l'ai désactivé en attendant, faudra que je trouve
pourquoi (sans doute parce que ce code est appelé après que tout le
reste des cshrc "officiels" soient executés ?)...
--
Rémi Moyen
Vincent Lefevre
Le #16547381
Dans l'article Rémi Moyen
On Aug 14, 12:14 pm, Jean-Marc Bourguet > Rémi Moyen > > Tiens, c'est vrai que quand je lance une nouvelle console, il faut
> > bien 10 secondes avant que j'ai le prompt, sans doute à cause de 40
> > 000 fichiers de configs dans tous les sens.



Ce qui est bien à l'origine de mon problème, d'ailleurs, je confirme :
Si je supprime mon .cshrc, less met 1 à 2 secondes pour se lancer, à
peine plus que si je ne définis pas LESSOPEN.



Je crois que c'est l'option -f qui permet d'éviter que le .cshrc ne
soit lu. Mais là, ce n'est pas possible de l'utiliser. "less" prend
peut-être en compte la variable d'environnement SHELL pour lessopen.
Tu peux toujours essayer...

--
Vincent Lefèvre 100% accessible validated (X)HTML - Blog: Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Publicité
Poster une réponse
Anonyme