Можно ли использовать Terminal.app для соблюдения кодов выхода ANSI?
Я замечаю, что с переменной окружения TERM
, установленной как xterm
или xterm-256color
, что утилита Mac OS Xs Terminal.app соответствует большинству кодов выхода ANSI, как минимум, когда эти escape-коды относятся к изменению цвета текста.
Например:
echo -e "\033[0;31mERROR:\033[0m It worked"
Выдает:
![Снимок экрана]()
Тем не менее, Im больше интересовался функциональностью манипулирования местоположением курсора, предоставляемой escape-кодами ANSI. К сожалению, этот тип кода не работает слишком хорошо в Terminal.app, из того, что Ive удалось собрать. Например, я хочу сделать что-то вроде этого:
echo -e "\033[sHello world\033[uG'day"
ESC[s
Сохраняет текущую позицию курсора, тогда как ESC[u
восстанавливает последнюю сохраненную позицию. В результате выполнения script выше Id ожидает, что пять символов в "G'day" перечеркнут пять символов "Hello" после того, как курсор был перемещен, создавая следующее:
G'day world
В самом деле, это именно то, что я получаю с iTerm2.app, ConEmu для Windows (выполняется либо MinGW, либо MSYS Git с копией bash.exe) и т.д. То, что я вижу в Terminal.app, это:
Hello worldG'day
Есть ли причина для этого, кроме того, что Terminal.app просто не поддерживает эти коды? Есть ли способ включить эту функциональность? Есть ли шанс, что у меня что-то неправильно сконфигурировано? Моя настройка TERM? Что-то еще?
Ive искал везде, но havent нашел что-то относящееся к Terminal.app, в частности. Мне показалось странным, что он будет поддерживать цветной текст через escape-коды ANSI, но не переместить курсор по той же технологии. Это похоже на довольно произвольное подмножество довольно четко определенного стандарта. То, что заставляет меня думать, что у меня что-то неправильно сконфигурировано, а не на том, что Terminal.app - это тот, кто виноват... но, я полагаю, его возможно, что это просто невозможно сделать. (Вероятно, одна из причин, по которой iTerm2 существует в первую очередь?)
Если кто-то может пролить свет на эту ситуацию, то очень ценю!
UPDATE
Итак, я немного побольше читал и экспериментировал, и обнаружил следующую странность:
Посмотрите на n.m. ответ ниже, я решил записать байты, возвращаемые tput
в файл, чтобы посмотреть, как они отличаются от обычной инструкции ANSI.
$ echo "$(tput sc)Hello world$(tput rc)G'day" > out.bin
$ cat -e out.bin
^[7Hello world^[8G'day$
Кажется, что все работает так, как ожидалось, если я отправлю ему последовательности ESC
7
и ESC
8
, но НЕ, если я отправлю его ESC
[s
и ESC
[u
, что, как я понимаю, является более типичным представлением кодов ANSI SCP и RCP (соответственно сохранить положение курсора и положение курсора). Так как поместить десятичные символы ASCII 7
или 8
рядом с эскизным восьмеричным представлением байта невозможно (\0337
!= ESC
), вместо этого вместо этого можно использовать переменные окружения, чтобы не полагаться на tput
:
$ esc=$'\033'
$ csi="${esc}["
$ echo "${csi}0;31mERROR:${csi}0m It worked."
ERROR: It worked. # Color works, as before
$ echo "${csi}sHello world${csi}uG'day"
Hello worldG'day # No dice
$ echo "${esc}7Hello world${esc}8G'day"
G'day world # Success
Я не уверен, почему это так. Если ESC
7
и ESC
8
являются своего рода проприетарным или настраиваемым кодом для ANSI SCP и RCP, который может варьироваться от терминальной реализации до реализации терминала, это объясняет мне, почему tput
был созданный в первую очередь.
К сожалению, я не могу использовать tput
для того, над чем я сейчас работаю, поскольку я не работаю исключительно в среде bash. Мне более любопытно, как интерпретируются необработанные байты с терминала на терминал и, более конкретно, , есть ли способ заставить Terminal.app соблюдать одни и те же escape-коды ANSI, что и все остальные эмуляторы терминала я Кажется, у нас не было проблем. Возможно ли это?. В этот момент я начинаю думать, что это просто не может быть, что хорошо, но было бы хорошо знать наверняка и, возможно, также узнать причину.
Ответы
Ответ 1
Не используйте коды ANSI. Используйте правильные методы на основе terminfo. Терминалы на основе Xterm не указаны для поддержки всех кодов ANSI. Некоторые делают для совместимости, некоторые - нет.
Сохранение позиции курсора задается командой tput sc
, а позиция курсора восстановления tput rc
.
echo -e "$(tput sc)Hello world$(tput rc)G'day"
должен работать на любом терминале, который поддерживает эти последовательности.
Чтобы увидеть читаемое представление поддерживаемых последовательностей, используйте команду infocmp
. Выходной сигнал может быть довольно длинным. Если вас интересуют sc
и rc
:
infocmp | grep --color ' [sr]c='
Отказ от ответственности: протестирован на моей машине Linux, у вас нет Mac.
UPDATE
Terminal.app моделируется после xterm, а xterm моделируется после терминала VT100. VT100 не реализовывал последовательности CSI u
и CSI s
, но использовал DEC private ESC 7
и ESC 8
последовательности (источник). Позже модели VT поддерживали как CSI s/u
, так и ESC 7/8
под другим именем и с немного отличающимися функциональными возможностями (источник).
ECMA 48, похоже, не указывает никаких последовательностей позиции курсора сохранения/восстановления (источник (PDF)), или я не смог найти их там. Я не знаю, откуда CSU s/u
. Их имя в документации VT510 предполагает, что они каким-то образом связаны с ШОС. Этот источник предполагает, что они на самом деле являются частными последовательностями без стандартного значения. Терминалы SUN используют SCI s
для выполнения reset. Вероятно, это ошибка для маркировки этих двух последовательностей ANSI.
Современные версии xterm и других терминальных программ X11 (konsole, rxvt...) поддерживают как ESC 7/8
, так и CSI s/u
, но база данных terminfo рекламирует только ESC 7/8
. Terminal.app, по-видимому, поддерживает только ESC 7/8
.