Есть ли переменная окружения?
Да. Это TERMпеременная окружения. Это потому, что есть несколько вещей, которые используются как часть процесса принятия решений.
Здесь сложно обобщить, потому что не все программы согласовывают единую схему принятия решений. На самом деле GNUgrep , упомянутый в ответе М. Китта, является хорошим примером выброса, который использует несколько необычный процесс принятия решений с неожиданными результатами. Поэтому в общих чертах:
- Стандартный вывод должен быть оконечным устройством, как определено
isatty() .
- Программа должна иметь возможность искать запись для типа терминала в базе данных termcap / terminfo.
- Поэтому для поиска должен быть тип терминала.
TERMПеременная среды должна существовать и его значение должно соответствовать записи в базе данных.
- Поэтому должна быть база данных terminfo / termcap. В некоторых реализациях подсистемы местоположение базы данных termcap может быть указано с помощью
TERMCAPпеременной среды. Так что на некоторых реализациях есть второй переменная окружения.
- Запись termcap / terminfo должна указывать, что тип терминала поддерживает цвета. В
max_colorsterminfo есть поле. Он не установлен для типов терминалов, которые на самом деле не имеют цветовых возможностей. Действительно, есть 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не учитывает это, наивно ожидая немедленного переноса строки , и его цветной вывод идет неправильно.
Цветной вывод не простая вещь.
дальнейшее чтение