La commande hl, surligneur automatique permettant de coloriser les informations importantes d'un texte, décrites par des expressions régulières, dispose depuis la version 1.106 de fonctions telles que l'autocomplétion, le contrôle de séquentialité, et une manipulation simplifiée des configurations. Cet article vous en explique l'utilisation.
Rappel
La commande hl est une commande système, écrite en langage C, permettant de coloriser de 42 couleurs différentes des fragments de textes lus sur son entrée standard et provenant de fichiers ou de résultats de commandes. Les directives de colorisation sont données au moyen d'expressions régulières et d'options de spécifications de couleurs associées.
La commande de colorisation hl, que certains utilisateurs de la ligne de commandes commencent à bien connaître maintenant, peut être considérée comme un surligneur automatique qui met en évidence les informations ou les particularités d'un texte. Elle dispose dans la version 1.106 de nouvelles fonctionnalités qui la rendent encore plus puissante et plus pratique à utiliser, à savoir : la possibilité de spécifier l'emplacement des fichiers de configuration, le contrôle de séquentialité (détection de rupture de séquences), l'autocomplétion des noms des configurations et la recherche de configuration par modèle (pattern) ou expression régulière. Nous allons examiner ces nouveautés afin de vous permettre de mieux les exploiter. Les scripts hl_tool et hl_conf qui facilitent certaines manipulations liées aux configurations seront également abordés.
Les lecteurs qui découvriraient cette commande pourront se reporter aux précédents articles parus dans Linux Pratique (voir [1] et [2]).
1. Besoin d'assouplissement de la configuration
1.1 Centralisation de l'installation
Les versions antérieures à la version 1.93 présentaient l'inconvénient de nécessiter d'effectuer une installation sur chacune des machines sur lesquelles la commande hl devait pouvoir être utilisée, car elles n'étaient capables de traiter que deux fichiers de configurations : /etc/default/hl et $HOME/.hl.cfg. Le chemin d'accès (pathname) du fichier de configurations global (/etc/default/hl) n'était pas paramétrable et devait de ce fait résider sur la machine sur laquelle la commande hl est exécutée. Lorsque ces machines sont en petit nombre, cela ne constitue pas un réel problème, mais si l'on doit rendre la commande utilisable depuis un grand nombre de machines, cela peut rapidement devenir ennuyeux, à la fois en termes d'installation et en termes de mises à jour ou de diffusion de configurations. On peut bien sûr utiliser des logiciels d'installation et de mise à jour comme Puppet ou Ansible, mais cela demande un travail additionnel de configuration, maintenance, diffusion... Avoir la possibilité de déposer la commande et ses différents fichiers de configurations sur un système de fichiers réseau (NFS, Lustre, GPFS...) est une solution permettant de minimiser ces tâches d'installation et de mise à jour.
Une autre contrainte à l'installation des versions précédentes était la nécessité de disposer des droits root afin de pouvoir copier le fichier de configurations commun dans le répertoire système /etc/default. Or les utilisateurs d'un poste de travail sous Linux ne disposent pas toujours de ces droits.
De plus, avec l'augmentation du nombre de configurations, la taille de l'unique fichier /etc/default/hl commençait à devenir relativement importante et son organisation était très discutable : les différentes configurations étaient à peu près classées par ordre alphabétique, mais tous les thèmes étaient mélangés dans un unique fichier peu pratique à utiliser. J'ai donc décidé de l'éclater en une multitude de petits fichiers de configuration afin de faciliter leur manipulation.
Cet éclatement présente l'avantage de pouvoir organiser les configurations par thème, par exemple de la façon suivante :
- commandes système ;
- fichiers de logs ;
- fichiers de configuration de logiciels ;
- gestion de dates ;
- etc.
Cela dit, l'apparition de cet ensemble de fichiers de configurations conduit à un nouveau problème : trouver une méthode simple permettant de spécifier les noms des fichiers à utiliser, ainsi que leur localisation dans le cas où l'on souhaiterait définir leurs priorités d'utilisation.
1.2 Spécification des fichiers de configurations
Le paramétrage était donc indispensable, et la solution la plus immédiate était l'utilisation d'une variable d'environnement. La première qui a été ajoutée est HL_CONF, qui est utilisée dans un usage similaire aux variables PATH et LIBPATH, à savoir une liste de pathnames de répertoires dans lesquels sont susceptibles de se trouver les fichiers de configurations.
Voici un exemple de contenu d'une variable PATH :
Pour rappel, cette variable est utilisée de la manière suivante : lorsqu'un utilisateur tape une commande dans un interpréteur de commandes, comme sh ou bash par exemple, le fichier à exécuter est recherché dans les répertoires spécifiés dans la variable PATH, dans l'ordre dans lequel ils sont spécifiés (de gauche à droite). Dans l'exemple précédent, si l'on tape la commande :
celle-ci sera recherchée respectivement dans les répertoires :
- /usr/local/sbin,
- /usr/local/bin,
- /usr/sbin,
- /usr/bin,
- etc.
La recherche s'arrête dès qu'un fichier exécutable portant le nom de la commande est trouvé, et la commande correspondante est alors exécutée. Le fonctionnement de la recherche d'une configuration via la variable HL_CONF sera identique : la liste des pathnames est parcourue à la recherche de répertoires ou de fichiers de configuration, tous les fichiers de configurations rencontrés sont lus et stockés en mémoire sous forme de liste, en respectant l'ordre des pathnames et des définitions de configurations dans les fichiers, de façon à permettre aux utilisateurs de définir la priorité dans la recherche des configurations.
Par souci de compatibilité avec les versions précédentes, et donc pour pouvoir continuer à utiliser si nécessaire le fichier /etc/default/hl, la spécification de fichiers est également autorisée, en plus de celle des répertoires.
La question du nommage des fichiers de configurations à traiter, stockés dans les répertoires nommés dans la variable HL_CONF, a été soulevée immédiatement après, et les différentes possibilités ont débouché rapidement sur le besoin de pouvoir spécifier une liste de modèles (patterns) permettant une description générique du nom des fichiers utilisés pour stocker les configurations. La fonction C capable d'interpréter ces modèles étant la fonction glob(), il était logique de nommer cette variable HL_CONF_GLOB. Son usage est, ici aussi, comparable à celui des variables PATH, LIBPATH, et HL_CONF, à ceci près que les éléments spécifiés ne sont pas des pathnames, mais des modèles (patterns) comme ceux utilisés par le shell. Grâce à ces possibilités de paramétrer la configuration, il va désormais être possible de centraliser les configurations sur un serveur, et de ne plus avoir à déployer les fichiers de configurations sur un ensemble de machines. Il sera donc possible d'accéder à un unique emplacement de fichiers de configuration accessibles via des serveurs de fichiers NFS, Lustre, GPFS, ou autres.
Les utilisateurs souhaitant utiliser la commande hl et ses fichiers de configurations de façon centralisée pourront les utiliser en effectuant des montages des systèmes de fichiers où hl et les configurations sont hébergés, et en configurant de façon appropriée les variables PATH (pour hl) et HL_CONF et HL_CONF_GLOB (pour les configurations). Les paquets de gestion d'environnement, tels qu’environnent-modules ou Lmod, permettent de simplifier la mise à jour des variables d'environnement, et présentent un caractère dynamique de chargement/déchargement de module permettant, de plus, d'utiliser très simplement différentes versions d'une commande ou d'un ensemble de configurations, ce qui peut s'avérer très pratique lors de tests de préproduction. Cela dit, ce sujet dépasse le cadre de cet article et il ne sera pas développé ici.
1.3 Organisation des configurations
Les configurations peuvent maintenant être regroupées par thème dans différents fichiers. Il n'est pas utile de donner dans cet article la liste complète des groupes de configurations disponibles, car celle-ci s'accroît très fréquemment. Je n'en citerai que quelques-uns :
- hl_date.cfg : configurations liées aux dates, aux temps ou aux durées ;
- hl_errors.cfg : configurations liées aux erreurs et messages d'avertissement (warnings) ;
- hl_network.cfg : configurations liées à certaines commandes réseau, et aux adresses IP ;
- hl_syslog.cfg : configurations liées au fichier /var/adm/syslog ;
- hl_system.cfg : configurations liées à certaines commandes système.
Vous pourrez découvrir les autres vous-même en explorant les fichiers du répertoire config_files dans l'arborescence produite par git clone lors de l'installation, créer vos propres fichiers de configuration, et pourquoi pas en proposer certains à la communauté des utilisateurs.
2. Contrôle de séquentialité
La colorisation de texte effectuée par la commande hl est majoritairement spécifiée par des expressions régulières, basiques ou étendues : les chaînes correspondant aux expressions spécifiées sont affichées de la couleur indiquée par l'option associée à l'expression régulière. Mais il existe dans hl des fonctionnalités plus élaborées dans lesquelles la colorisation est influencée par le texte lu par la commande. Les options -A et -I permettent d'alterner les couleurs lorsque des valeurs dans le texte changent d'une ligne à l'autre, ou au contraire restent identiques (voir [2]). L'option -s présente dans la version 1.103 permet, quant à elle, de détecter des ruptures de séquences dans des fragments de texte décrits par des expressions régulières. Le besoin initial était de contrôler la séquentialité de nombres entiers, placés par exemple dans les noms de serveurs d'un fichier /etc/hosts, mais elle peut également être utilisée pour contrôler la séquentialité d'adresses IP. Et, très rapidement, cette fonction a été étendue pour que l'on puisse utiliser tout incrément entier autre que 1, et les opérations de soustraction, multiplication et division en plus de la simple addition. La syntaxe de cette option est devenue la suivante :
La figure 1 illustre le contrôle de séquentialité des adresses IP d'une part (en bleu) et celui des hostnames (en jaune). On peut y voir 3 ruptures de séquences : la première dans les adresses IP où l'on passe de 10.0.0.66 à 10.0.0.68, les deux autres dans les hostnames où l'on passe de node06 à node06 (au lieu de node07), puis de node06 à node08.
La figure 2 illustre le contrôle des définitions de constantes en hexadécimal dans un fichier header C, les constantes étant les bits d'un champ, chaque valeur est le double de la précédente.
3. Autocomplétion
3.1 Mécanisme
L'autocomplétion est une facilité proposée par certains interpréteurs de commande, notamment bash, pour compléter automatiquement les options ou arguments de certaines commandes, ou proposer différents choix possibles. Dans le cas de la commande hl, l'autocomplétion sera utilisée pour compléter sur la ligne de commandes le nom des configurations spécifiées à l'aide de deux tirets, en utilisant celles qui sont définies dans les fichiers de configurations déclarés à l'aide des variables HL_CONF et HL_CONF_GLOB.
3.2 Exemples
Si l'on veut lancer, par exemple, la commande suivante :
le fait de taper :
suivi de deux tabulations fera apparaître une liste de configurations dont le nom commence par dup :
il ne reste plus qu'à choisir celle que l'on veut utiliser parmi celles qui sont proposées.
Cette fonctionnalité est particulièrement pratique quand le nombre de configurations disponibles est important, et que l'on a oublié le nom de la configuration que l'on souhaite utiliser, ou que l'on a un doute sur le nom exact ou la syntaxe de la configuration à utiliser, par exemple : on_off ou on-off ?
Le mécanisme d'autocomplétion pour la commande hl est réalisé grâce au script hl/completion/complete_hl, qui contient la commande suivante :
La commande :
passée en argument de complete permet de récupérer la liste des noms de configurations utilisées, chaque nom étant précédé de deux tirets, tel qu'on doit le spécifier en argument de hl. Voici les dix premières lignes produites par cette commande :
Lancer le script hl/completion/complete_hl depuis la ligne de commandes ou depuis un fichier d'initialisation tel que $HOME/.bashrc permet ensuite de bénéficier de l'autocomplétion des noms de configurations.
4. Recherche de configurations
Quand le nombre de configurations définies devient important, la recherche d'une configuration donnée peut devenir fastidieuse. Afin de faciliter la localisation et la récupération de configurations, en vue de les corriger, de les copier ou de les modifier, deux nouvelles options ont été ajoutées : la première, -p, utilisant des expressions de sélection (patterns) comparables à celles du shell, la deuxième, -P, utilisant des expressions régulières, basiques ou étendues (selon l'absence ou la présence de l'option -e).
Leur utilisation est la suivante :
Ces deux options vous facilitent la personnalisation dans le cas où vous souhaiteriez utiliser une configuration existante avec d'autres couleurs que celles qui sont définies, ou avec des expressions régulières légèrement différentes. Dans ce cas, la manipulation est simple, il suffit de :
- récupérer la configuration à personnaliser en utilisant les options -vop ou -voP suivies du nom de la configuration et de rediriger la sortie de la commande hl vers un fichier temporaire ;
- éditer le fichier temporaire pour modifier la configuration comme il vous plaît ;
- intégrer le contenu du fichier temporaire dans votre fichier $HOME/.hl.cfg (ou tout autre fichier de configuration prioritaire devant la configuration d'origine).
Voyons maintenant quelques exemples.
4.1 Recherche par modèle (pattern)
La commande :
recherche la localisation des configurations dont le nom commence par dupA.
affiche la localisation de la configuration dHMS ainsi que le détail de ses options.
La commande :
a le même effet que la commande précédente, mais affiche les informations sur stdout et non sur stderr, ce qui présente l'avantage de pouvoir les rediriger simplement vers un fichier, ou vers un autre process (via un pipe).
4.2 Recherche par expression régulière
L'option -P est similaire à l'option -p du paragraphe précédent, mais les patterns sont remplacés par des expressions régulières, ce qui permet d'avoir plus de finesse dans la spécifications des expressions.
Voici un exemple utilisant une expression régulière étendue :
5. Scripts d'administration
5.1 Script hl_tool
Le script hl_tool a été conçu pour faciliter la gestion des configurations : lorsque l'on manipule de nombreuses configurations, on a rapidement des besoins qui ne peuvent plus être réglés par de simples commandes système, et des fonctions telles que, par exemple, la localisation d'une configuration, la comparaison de deux versions d'une même configuration dans deux fichiers différents ou la récupération d'informations sur une configuration nécessitent de bien connaître la syntaxe des fichiers de configuration, et de ne pas rechigner à taper des commandes un peu compliquées et souvent fastidieuses. Le script hl_tool permet de nous décharger de beaucoup de ce genre de tâches.
Son usage est donné par la figure 3.
Les principales fonctions qu'il implémente sont les suivantes :
- lister les chemins d'accès (pathnames) des fichiers de configurations utilisés ;
- comptabiliser les nombres d'occurrences des configurations et les classer en ordre croissant ;
- afficher les différences entre deux définitions d'une même configuration dans deux fichiers de configurations distincts ;
- lister les fichiers et/ou répertoires définis en variable d'environnement ;
- lister les configurations définies dans un fichier spécifié ;
- lister les fichiers contenant une configuration spécifiée ;
- lister l'ensemble des configurations utilisées ;
- calculer les checksums des configurations définies afin d'identifier les variantes ;
- lister les configurations spécifiques à un fichier de configuration donné ;
- afficher le nombre d'options utilisé par chaque configuration pour l'ensemble des configurations utilisées.
Voici quelques exemples d'utilisation du script hl_tool.
5.1.1 Calcul de checksum
L'option -m provoque le calcul d'une somme de contrôle (checksum) pour toutes les occurrences d'une configuration donnée dans l'ensemble des fichiers de configurations utilisés (i.e. : pointés par les variables HL_CONF et HL_CONF_GLOB), ce qui permet d'identifier les doublons et éventuellement de les supprimer. Par exemple :
nous indique que les configurations nommées hl dans les deux fichiers cités ci-dessus sont identiques, et que celle qui est définie dans le fichier $HOME/.hl.cfg peut être supprimée.
Au contraire, la commande suivante :
nous affiche des checksums différents pour la configuration diff_tree2, donc que les variantes sont différentes. On peut utiliser l'option -d du script pour afficher les différences entre ces deux variantes.
5.1.2 Affichage de différences
La commande :
affiche le résultat visible sur la figure 4.
5.2 Script hl_conf
Le script hl_conf a été créé pour faciliter la lecture des fichiers de configurations de hl : il permet de coloriser simplement une configuration donnée, un ensemble de configurations ou un fichier de configurations. Son usage est très simple : il suffit d'envoyer la (les) colorisation(s) à coloriser à hl_conf via un tube de communication (pipe).
Voici un exemple de commande, et son résultat visible en figure 5.
Conclusion
La commande hl est, depuis six ans, en évolution rapide, avec des ajouts fréquents de nouvelles configurations et de nouvelles fonctionnalités, telles que celles dont nous venons de parler. Une manipulation plus simple des seuils est également à l'étude, ainsi que la création de futures configurations pour la colorisation des logs, et des fonctionnalités destinées à améliorer la lecture des fichiers HTML, XML, et la lecture de traces d'exécution de programmes afin d'en faciliter la mise au point.
Si vous êtes un adepte de la ligne de commandes et de la manipulation de données textuelles (données utilisateur, fichiers de logs ou de configuration...), apprendre à utiliser cette commande avec les configurations fournies ou en définissant vos propres configurations, pourra vous faire gagner beaucoup de temps et fiabiliser vos traitements et/ou vos résultats. Et, chose importante, elle vous permettra aussi de gagner en sérénité et en efficacité en vous assistant lors de la recherche d'informations à l'écran ou lors de certains contrôles de cohérence, ce qui s'avère particulièrement important lors de la résolution des incidents en production. N'hésitez pas à consulter la page principale du site de la commande hl, ainsi que la page wiki de ce même site.
Enfin, si vous avez défini de nouvelles configurations qui pourraient être utiles à la communauté des utilisateurs (Linux, BSD, macOS...) et que vous souhaitez les partager, sachez que votre participation sera la bienvenue et que vous laisserez grâce à elle votre nom dans l'histoire de cette commande.
Références
[1] Martial Bornet, « Colorisez vos textes avec la commande hl », Linux Pratique n°93,
https://connect.ed-diamond.com/Linux-Pratique/LP-093/Colorisez-vos-textes-avec-la-commande-hl
[2] Martial Bornet, « Tirez parti de la colorisation pour faciliter la lecture de vos données », Linux Pratique HS n°46, https://connect.ed-diamond.com/Linux-Pratique/LPHS-046/Tirez-parti-de-la-colorisation-pour-faciliter-la-lecture-de-vos-donnees
[3] Site GitHub de téléchargement de la commande hl : https://github.com/mbornet-hl/hl
Pour aller plus loin
Pour pouvoir définir de nouvelles configurations adaptées à ses propres besoins, ou modifier les configurations fournies sur [3], il est souvent indispensable de bien maîtriser les expressions régulières et leur syntaxe. Si vous ne vous sentez pas à l'aise dans ce domaine, reportez-vous à la documentation et aux ouvrages ou articles traitant de ce sujet pour monter en compétence et profiter de la pleine puissance de hl grâce à celle des expressions régulières. Le temps que vous passerez à l'étude de ce sujet sera amplement rentabilisé par la suite, augmentera vos compétences et vous donnera un net avantage sur ceux qui ne les maîtrisent pas.