![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Кольорологія терміналів
Ув вікіпідіа написано шо хадварні термінали VT100 (продавалися з 1978 року) та VT220 (1983) були монохромні (кольорові варіянти, напевно, лише для заможних верств гіпадрілів). Terminfo ув лайнаксі про ці термінали містить ту саму інформацію:
$ for i in dumb vt100 vt220 screen xterm $TERM; do printf "%-20s" $i; TERM=$i tput colors; done
dumb -1
vt100 -1
vt220 -1
screen 8
xterm 8
xterm-256color 256
Кілька днів тому, нєкто Поттерінґ, мастодонів про діфолтне значення
TERM
, яке обирає systemd:
'The default fallback $TERM we so far picked has been "vt220" … This deemed us to be a good choice, since (unlike the better known vt100) these kind of terminals support PageUp/PageDown keys'
Загалом, ув terminfo дивляться зазвичай тільки ютіліти які для користувацького інтерхфейсу використовують ncurses; решта вгадує можливості терміналу шляхом слідкування за візерунками руху небесних тіл, e.g.:
- чи є змінна середовища
COLORTERM
(нещодавно обраний шлях systemd); - змінна середовища
NO_COLOR
(я би віддав перевагу, навпаки, щось на кшталтCOLOR=1
, бо діфолтне плювання кольорами ув консолі є страшенний несмак); - дивитися на
TERM
і шукати збіг ув своїй вкомпайлений (не жарт) табличці, як то робить ls з coreutils; - механізма terminal-colors.d(5) з util-linux, яким користується ніхто, окрім деяких ютіліт з util-linux.
Лайнаксний ls, звичайно, перемагає ув конкурсі найдебільнішого рішення.
Воно друкує барвами для vt100, тому що протягом компіляції coreutils хапається текстовий хфайла з налаштунками для dircolors(1), який має ось такі рядки:
TERM vt100
TERM xterm*
Цей хфайл (його копія зазвичай є ув /etc/DIR_COLORS
) скрипта
перловий конвертує ув символьного масива
$ head -c7 src/dircolors.hin # ув ріпо coreutils
# Confi
$ (head -c61 && printf 🤡 && tail -c39) < <(src/dcgen src/dircolors.hin)
static char const G_line[] =
{
'#',' ','C','o','n','f','i',🤡,'r','i','a','b','l','e','s','.',0,
};
який потім інклудиться як dircolors.h
ув ls.c
, де є хфункція
/* Check if the content of TERM is a valid name in dircolors. */
static bool known_term_type(void) {
char const *term = getenv("TERM");
if (!term || !*term)
return false;
char const *line = G_line;
while (line - G_line < sizeof(G_line)) {
if (STRNCMP_LIT(line, "TERM ") == 0) {
if (fnmatch(line + 5, term, 0) == 0)
return true;
}
line += strlen(line) + 1;
}
return false;
}
dircolors(1) також парсить нещасну G_line
та друкує 0 інструкцій для
ls, коли TERM
є відсутня чи несе невідоме значення:
$ env -i SHELL=/bin/sh dircolors
LS_COLORS='';
export LS_COLORS
У чому сенс тоді, навіть за відсутності LS_COLORS
, розмальовуювати
множинні character devices з директоріями (довгий масив
color_indicator[]
ув ls.c
, якщо комусь цікаво), але полишати файли
звичайні (кольори для яких G_line
має), залишається невідомим.