Y a-t-il un avantage objectif à échapper aux séquences par rapport au débit?

11

Dans les .*rcfichiers des gens que je vois en ligne ou dans divers codes, j'ai tendance à voir beaucoup de gens qui utilisent manuellement les séquences d'échappement ANSI au lieu de les utiliser tput.

J'ai compris que tputc'était plus universel / sûr, donc cela me fait me demander:

Y a-t-il une raison objective d'utiliser des séquences d'échappement à la place de tput? (Portabilité, robustesse aux erreurs, terminaux inhabituels ...?)

Captain Man
la source
D'un autre côté de la question de la portabilité, MobaXterm fonctionnera avec printfles séquences d'échappement ANSI, mais tputéchouera (au moins sur ma boîte).
Wildcard

Réponses:

6

tputpeut gérer des expressions (par exemple dans sgret setaf) que le shell-scripteur typique trouverait moins qu'utilisable. Pour avoir une idée de ce qui est impliqué, voir la sortie de infocmpavec l' -foption (formatage) appliquée. Voici un exemple d'utilisation de ces chaînes à partir des descriptions terminfo de xterm :

xterm-16color|xterm with 16 colors,
        colors#16,
        pairs#256,
        setab=\E[
                %?
                        %p1%{8}%<
                        %t%p1%{40}%+
                %e
                        %p1%{92}%+
                %;%dm,
        setaf=\E[
                %?
                        %p1%{8}%<
                        %t%p1%{30}%+
                %e
                        %p1%{82}%+
                %;%dm,
        setb=
                %p1%{8}%/%{6}%*%{4}%+\E[%d%p1%{8}%m%Pa
                %?%ga%{1}%=
                        %t4
                %e%ga%{3}%=
                        %t6
                %e%ga%{4}%=
                        %t1
                %e%ga%{6}%=
                        %t3
                %e%ga%d
                %;
                m,
        setf=
                %p1%{8}%/%{6}%*%{3}%+\E[%d%p1%{8}%m%Pa
                %?%ga%{1}%=
                        %t4
                %e%ga%{3}%=
                        %t6
                %e%ga%{4}%=
                        %t1
                %e%ga%{6}%=
                        %t3
                %e%ga%d
                %;
                m,
        use=xterm+256color,
        use=xterm-new,

Le formatage divise les choses - un script ou un programme pour faire de même devrait suivre ces rebondissements. La plupart des gens abandonnent et utilisent simplement les cordes les plus faciles.

La fonction 16 couleurs est empruntée à IBM aixterm, qui mappe 16 codes chacun pour le premier plan et l'arrière-plan sur deux plages;

  • premier plan sur 30-37 et 90-97
  • fond sur 40-47 et 100-107

Un script simple

#!/bin/sh
TERM=xterm-16color
export TERM
printf '    %12s %12s\n' Foreground Background
for n in $(seq 0 15)
do
    F=$(tput setaf $n | cat -v)
    B=$(tput setab $n | cat -v)
    printf '%2d  %12s %12s\n' $n "$F" "$B"
done

et la sortie montre comment cela fonctionne:

      Foreground   Background
 0        ^[[30m       ^[[40m
 1        ^[[31m       ^[[41m
 2        ^[[32m       ^[[42m
 3        ^[[33m       ^[[43m
 4        ^[[34m       ^[[44m
 5        ^[[35m       ^[[45m
 6        ^[[36m       ^[[46m
 7        ^[[37m       ^[[47m
 8        ^[[90m      ^[[100m
 9        ^[[91m      ^[[101m
10        ^[[92m      ^[[102m
11        ^[[93m      ^[[103m
12        ^[[94m      ^[[104m
13        ^[[95m      ^[[105m
14        ^[[96m      ^[[106m
15        ^[[97m      ^[[107m

Les nombres sont divisés car aixterm utilise les plages 30-37 et 40-47 pour correspondre aux couleurs ECMA-48 (également appelées "ANSI") et utilise la plage 90-107 pour les codes non définis dans la norme.

Voici une capture d'écran avec xterm using TERM=xterm-16color, où vous pouvez voir l'effet.

entrez la description de l'image ici

Lectures complémentaires:

Thomas Dickey
la source
Je prouve peut-être votre point, mais quel est le problème avec ces expressions? De regarder le manuel pour infocmp je me rends compte qu'ils sont des déclarations if-then-else ... mais je ne l' ai jamais vu et je ne parviens pas à googler pour elle, c'est tout ce que je trouve, mais je ne suis pas sûr que c'est Que se passe-t-il ici. Merci!
Captain Man
2

Venant d'une époque où les plates-formes UNIX pouvaient avoir une variété de périphériques attachés, je préfère de loin tput et ses amis aux séquences d'échappement littérales.

Je pense que la vraie raison est que la plupart des gens ne connaissent tout simplement pas les fichiers / bibliothèques tputassociés .terminfotermcap

roaima
la source
1

L'une des raisons est qu'il tputs'agit de la commande externe, elle peut donc s'exécuter plus lentement que les codes d'échappement shell intégrés. Une autre chose est que l'on peut facilement créer un liners combinant des codes d'échappement ANSI avec des caractères d'échappement spécifiques au shell, comme dans bashinvite par exemple:

PS1='\[\033[1;32m\]\u@\h\[\033[1;34m\] \w >\[\033[0m\] '

de même dans zsh:

PS1=$'%{\e[1;32m%}%n@%m%{\e[1;34m%} %3~> %{\e[0m%}'

Ici, tout est clair et compact. Avec tputun, il faudrait le diviser en plusieurs lignes ou le rendre beaucoup plus long et complexe, en l'exécutant tputplusieurs fois, etc.

jimmij
la source
1
Avec tput vous pouvez toujours faire des oneliners, PS1="$(tput setaf 2)\u@\h$(tput reset) >
Captain Man
2
En fait, ce serait $(tput sgr0)pour la fin, mais convenir que tput est une amélioration.
Thomas Dickey