Есть ли переменная окружения?
Да. Это TERM
переменная окружения. Это потому, что есть несколько вещей, которые используются как часть процесса принятия решений.
Здесь сложно обобщить, потому что не все программы согласовывают единую схему принятия решений. На самом деле GNUgrep
, упомянутый в ответе М. Китта, является хорошим примером выброса, который использует несколько необычный процесс принятия решений с неожиданными результатами. Поэтому в общих чертах:
- Стандартный вывод должен быть оконечным устройством, как определено
isatty()
.
- Программа должна иметь возможность искать запись для типа терминала в базе данных termcap / terminfo.
- Поэтому для поиска должен быть тип терминала.
TERM
Переменная среды должна существовать и его значение должно соответствовать записи в базе данных.
- Поэтому должна быть база данных terminfo / termcap. В некоторых реализациях подсистемы местоположение базы данных termcap может быть указано с помощью
TERMCAP
переменной среды. Так что на некоторых реализациях есть второй переменная окружения.
- Запись termcap / terminfo должна указывать, что тип терминала поддерживает цвета. В
max_colors
terminfo есть поле. Он не установлен для типов терминалов, которые на самом деле не имеют цветовых возможностей. Действительно, есть TERMINFO соглашение , что для каждого типа терминала благовидного есть другая запись с -m
или -mono
добавляется к имени , которое не заявляет нет возможности цвета.
- Запись termcap / terminfo должна предоставлять программе возможность изменять цвета. Есть
set_a_foreground
и set_a_background
поля в terminfo.
Это немного сложнее, чем просто проверка isatty()
. Он сделан дополнительно осложняется несколькими вещами:
- Некоторые приложения добавляют параметры командной строки или флаги конфигурации, которые отменяют
isatty()
проверку, так что программа всегда или никогда не предполагает, что в качестве ее вывода используется (окрашиваемый) терминал. Например:
- GNU
ls
имеет параметр --color
командной строки.
- BSD
ls
рассматривает CLICOLOR
(его отсутствие означает никогда ) и CLICOLOR_FORCE
(его присутствие означает всегда ) переменные окружения, а также использует параметр -G
командной строки.
- Некоторые приложения не используют termcap / terminfo и имеют аппаратные ответы на значение
TERM
.
- Не все терминалы используют последовательности SGR ECMA-48 или ISO 8613-6, которые несколько иначе называют «escape-последовательностями ANSI», для изменения цвета. Механизм termcap / terminfo фактически предназначен для изоляции приложений от непосредственного знания точных управляющих последовательностей. (Более того, есть аргумент, что никто не использует последовательности SGR ISO 8613-6, потому что все согласны с ошибкой использования точки с запятой в качестве разделителя для последовательностей SGR цвета RGB. Стандарт фактически определяет двоеточие.)
Как уже упоминалось, GNU на grep
самом деле демонстрирует некоторые из этих дополнительных сложностей. Он не обращается к termcap / terminfo, жестко связывает последовательности управления для передачи и передает ответ на TERM
переменную окружения.
Порт Linux / Unix этого есть этот код , который позволяет colourization только тогда , когда TERM
переменная окружения существует и его значение не совпадает Проводное имя dumb
:
ИНТ
should_colorize (void)
{
char const * t = getenv ("TERM");
return t && strcmp (t, "dumb")! = 0;
}
Так что, даже если TERM
это так xterm-mono
, GNU grep
решит испускать цвета, хотя другие программы, такие как vim
, не будут.
Порт Win32 него есть этот код , который позволяет colourization либо когда TERM
переменная окружения не существует , или если она существует , и его значение не совпадает Проводное имя dumb
:
ИНТ
should_colorize (void)
{
char const * t = getenv ("TERM");
возвращение ! (t && strcmp (t, "dumb") == 0);
}
grep
Проблемы GNU с цветом
grep
Окраска GNU на самом деле печально известна. Поскольку он на самом деле не выполняет надлежащую работу по построению вывода терминала, а просто обвиняет в нескольких зашитых последовательностях управления в различных точках его вывода в тщетной надежде, что это достаточно хорошо, он на самом деле отображает неправильный вывод в определенных обстоятельствах.
В этих обстоятельствах нужно раскрасить что-то, что находится на правом краю терминала. Программы, которые правильно выводят данные с терминала, должны учитывать правильные поля справа. В дополнение к небольшой вероятности того, что терминал может их не иметь (а именно auto_right_margin
поле в terminfo), поведение терминалов, которые имеют автоматические правые поля, часто соответствует прецеденту DEC VT для переноса ожидающих строк . GNU grep
не учитывает это, наивно ожидая немедленного переноса строки , и его цветной вывод идет неправильно.
Цветной вывод не простая вещь.
дальнейшее чтение