Программное определение escape-кода ANSI, поддерживаемого терминалом

Программное определение escape-кода ANSI, поддерживаемого терминалом

Я экспериментировал со скриптами оболочки, использующими коды ANSI, и обнаружил, что по той или иной причине поддерживаются разные коды escape-последовательности в зависимости от вашего терминала/ОС.

В некоторых случаях я неожиданно получаю кучу неразобранного мусора, что, как я предполагаю, означает, что мой терминал (на Mac OS) не поддерживает используемый escape-код, хотя в нескольких местах я читал, что это одно и то же:

27 = 033 = 0x1b = ^[ = \e

В поисках я нашелэтот вопрос об обнаружении поддержки, экранированной слэшем.

Выбранный ответ анализирует $TERMзначение для обнаружения

case $TERM in
  (|color(|?))(([Ekx]|dt|(ai|n)x)term|rxvt|screen*)*)
    PS1=$'\e\]0;$GENERATED_WINDOW_TITLE\a'"$PS1"
esac

Но мне интересно, насколько это надежно.

Существует ли стандартный способ проверки поддержки escape-кода (в первую очередь для Bash), или этот скрипт является по сути заурядным?

  • В качестве альтернативы, какой код выхода я могу использовать, чтобы «гарантировать» наиболее широкую поддержку?
  • А как насчет расширения echo -e?
  • Каковы общие рекомендации по переносимости/доступности/распространению дляскриптыкоторые используют или ссылаются на контрольные коды?

Этотоже приятное чтениедля тех, кто ищет информацию.

решение1

Вы имеете в виду какие-то конкретные операции?

Вот пример использованиярежим выдающегося, что на многих терминалах даст заметный результат:

tput smso; echo hello, world; tput rmso

Инструмент tputиспользует значение $TERMпеременной окружения для определения того, какие escape-последовательности выводить - если таковые имеются. Например

TERM=xterm
( tput smso; echo hello, world; tput rmso ) | hexdump -C
00000000  1b 5b 37 6d 68 65 6c 6c  6f 2c 20 77 6f 72 6c 64  |.[7mhello, world|
00000010  0a 1b 5b 32 37 6d                                 |..[27m|

TERM=dumb
( tput smso; echo hello, world; tput rmso ) | hexdump -C
00000000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a           |hello, world.|

Интересные характерные пары можно найти вman 5 terminfo, некоторые из которых приведены ниже:

  • Выдающиеся: smsoиrmso
  • Подчеркнуть: smulиrmul
  • Моргнуть (да!):blink
  • Двойная ширина: swidmиrwidm
  • Обеспечить регресс:rev
  • Отменить все:sgr0

Если вы хотите написать жирный текст, но только если терминал его понимает, то такой фрагмент подойдет

boldOn=$(tput smso)
boldOff=$(tput rmso)
# ...
printf "%s%s%s\n" "$boldOn" 'This message will be in bold, when available' "$boldOff"

решение2

На самом деле можно запросить у терминалов DEC (и их клонов и эмуляций, включая xterm) информацию об их возможностях; но не о поддержке отдельных escape-последовательностей (или ее полноте). UNIX обычно не использует эту функцию, полагаясь на базы данных termcap/terminfo (которые также документируют странности).

Для справки, последовательности — DA («Атрибуты устройства», стандарт ANSI) и DECID («Идентификация терминала», частная DEC).

Связанный контент