Есть ли какая-то объективная выгода для избежания последовательностей через tput?

11

В людских .*rcфайлах, которые я вижу в Интернете или в различном коде, я склонен видеть множество людей, которые вручную используют escape-последовательности ANSI вместо использования tput.

У меня было понимание, которое tputявляется более универсальным / безопасным, поэтому я удивляюсь:

Есть ли какая-то объективная причина, по которой следует использовать escape-последовательности вместо tput? (Переносимость, устойчивость к ошибкам, необычные терминалы ...?)

Капитан человек
источник
С другой стороны, вопрос о переносимости, MobaXterm будет работать с printfescape-последовательностями и ANSI, но tputне работает (по крайней мере, на моем компьютере).
Wildcard

Ответы:

6

tputможет обрабатывать выражения (например, в sgrи setaf), которые типичный shell-скриптер найдет менее пригодными для использования. Чтобы получить представление о том, что задействовано, смотрите вывод infocmpс -fпримененной опцией (форматирование). Вот один из примеров использования этих строк из описаний terminfo в 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,

Форматирование разделяет вещи - скрипт или программа, чтобы сделать то же самое, должны следовать этим поворотам. Большинство людей сдаются и просто используют самые простые струны.

16-цветная функция позаимствована у IBM aixterm, которая отображает 16 кодов для каждого переднего и заднего плана на два диапазона;

  • передний план на 30-37 и 90-97
  • фон на 40-47 и 100-107

Простой скрипт

#!/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

и выходные данные показывают, как это работает:

      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

Числа разделены, потому что aixterm использует диапазоны 30-37 и 40-47 для соответствия цветам ECMA-48 (также известный как "ANSI"), и использует диапазон 90-107 для кодов, не определенных в стандарте.

Вот скриншот с использованием xterm TERM=xterm-16color, где вы можете увидеть эффект.

введите описание изображения здесь

Дальнейшее чтение:

Томас Дики
источник
Я могу доказать вашу точку зрения, но как обстоят дела с этими выражениями? Просматривая руководство по infocmp, я понимаю, что это утверждения типа «если-то-еще» ... но я никогда не видел этого, и у меня возникают проблемы с поиском в Google, это все, что я нашел, но я не уверен, что это что здесь происходит. Спасибо!
Капитан Мэн
2

Исходя из того времени, когда к платформам UNIX можно было подключать различные устройства, я все еще предпочитаю tput и его друзей, а не буквальные escape-последовательности.

Я думаю , что реальная причина в том , что большинство людей просто не знают о том, tputи связанные с ним terminfo/ termcapфайлы и библиотеки.

roaima
источник
1

Одна из причин заключается в том, что tputэто внешняя команда, поэтому она может выполняться медленнее, чем встроенные экранирующие коды оболочки. Другое дело, что можно легко создать bashстроки, комбинирующие escape-коды ANSI с экранированными символами, специфичными для оболочки, как, например, в подсказке:

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

аналогично в zsh:

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

Здесь все понятно и компактно. При tputэтом потребуется разбить его на несколько строк или сделать его намного более длинной и сложной строкой, выполнить tputнесколько раз и т. Д.

jimmij
источник
1
С tput вы все еще можете делать одиночные игры, PS1="$(tput setaf 2)\u@\h$(tput reset) >
Капитан Мэн
2
На самом деле это было бы $(tput sgr0)для финала, но согласиться с тем, что tput является улучшением.
Томас Дики