Une ligne horizontale ajustée avant chaque PROMPT

21 février 2014

Ce serait chouette d’arriver à afficher une ligne horizontale dans le terminal, avant chaque commande : ça permettrait de séparer visuellement les résultats d’exécution.

Capture du 2014-02-21 12:04:47

C’est trop puissant le shell ! :-D

Evidemment, on veut un truc plus évolué que d’afficher un nombre de fois fixe le même caractère car notre fenêtre peut avoir une largeur quelconque. Exclues les solutions du type :

echo --------------------

En googlant, on trouve facilement plusieurs solutions, et après quelques tests et simplifications, je finis par cette commande :

export PROMPT_COMMAND="printf '%*s' `tput cols` | tr ' ' '_' "

Ça fonctionne presque parfaitement. Lorsqu’on lance le terminal, la ligne horizontale prend bien la largeur. Mais lorsqu’on change la taille de la fenêtre, la largeur n’est pas ajustée, et le résultat est moche :

Capture du 2014-02-21 12:26:55

Vous avez remarqué le trait qui se poursuit sur les lignes suivantes ?
C’est très moche, hein ?

Cette effet est du à l’ordre d’évaluation du shell : au moment où PROMPT_COMMAND est créée, toutes les variables sont d’abord évaluées. Si on regarde le contenu de PROMPT_COMMAND, on comprend mieux le problème :

$ echo $PROMPT_COMMAND
 printf '%*s' 237 | tr ' ' '_'

La commande tput est évaluée, et sa valeur vient alimenter statiquement PROMPT_COMMAND. Mais on peut contourner ce comportement, en obligeant l’évaluation systématique de tput. Voilà une solution :

#PRINT LINE BEFORE EACH PROMPT
 print_line() {
 printf '%*s\n' `tput cols` | tr ' ' '_'
 }
 export PROMPT_COMMAND="print_line"

L’astuce consiste à passer par une fonction (ici print_line) qui est évaluée à chaque appel. Il ne reste plus qu’à insérer ce bout de code dans votre .bashrc et voilà !