Czy jest jakaś zmienna środowiskowa?
Tak. Jest to TERM
zmienna środowiskowa. Jest tak, ponieważ istnieje kilka rzeczy, które są wykorzystywane w ramach procesu decyzyjnego.
Trudno tu uogólnić, ponieważ nie wszystkie programy zgadzają się co do schematu pojedynczej decyzji. W rzeczywistości GNU grep
, wspomniane w odpowiedzi M. Kitt, jest dobrym przykładem wartości odstającej, która wykorzystuje nieco nietypowy proces decyzyjny z nieoczekiwanymi wynikami. Dlatego bardzo ogólnie:
- Standardowe wyjście musi być urządzeniem końcowym, jak określono przez
isatty()
.
- Program musi być w stanie wyszukać rekord typu terminala w bazie danych termcap / terminfo.
- Dlatego musi istnieć typ terminala do wyszukiwania.
TERM
Zmienna musi istnieć, a jego wartość musi odpowiadać rekord bazy danych.
- Dlatego musi istnieć baza danych terminfo / termcap. W niektórych implementacjach podsystemu lokalizację bazy danych termcap można określić za pomocą
TERMCAP
zmiennej środowiskowej. Tak więc na niektórych implementacjach jest sekunda zmienna środowiskowa.
- Rekord termcap / terminfo musi stwierdzać, że typ terminala obsługuje kolory. W
max_colors
terminfo znajduje się pole. Nie jest ustawiony dla typów terminali, które tak naprawdę nie mają możliwości kolorowania. Rzeczywiście, istnieje konwencja terminfo, która dla każdego koloryzowalnego typu terminala zawiera inny rekord z nazwą -m
lub -mono
dołączony do nazwy, który nie określa możliwości kolorystycznych.
- Rekord termcap / terminfo musi umożliwiać programowi zmianę kolorów. W terminfo znajdują się
set_a_foreground
i set_a_background
pola.
Jest to nieco bardziej skomplikowane niż tylko sprawdzanie isatty()
. Wykonany jest dodatkowo skomplikowana przez kilka rzeczy:
- Niektóre aplikacje dodają opcje wiersza polecenia lub flagi konfiguracji, które zastępują
isatty()
sprawdzenie, tak że program zawsze lub nigdy nie zakłada, że ma (wyjściowy) terminal jako wyjście. Dla przykładów:
- GNU
ls
ma--color
opcję wiersza poleceń.
- BSD
ls
sprawdza zmienne środowiskowe CLICOLOR
(jego brak oznacza nigdy ) i CLICOLOR_FORCE
(jego obecność zawsze oznacza ), a także obsługuje -G
opcję wiersza polecenia.
- Niektóre aplikacje nie używają termcap / terminfo i mają wbudowane odpowiedzi na wartość
TERM
.
- Nie wszystkie terminale używają sekwencji SGR ECMA-48 lub ISO 8613-6, które są nieco błędnie nazywane „sekwencjami ucieczki ANSI” do zmiany kolorów. Mechanizm termcap / terminfo jest tak naprawdę zaprojektowany, aby odizolować aplikacje od bezpośredniej wiedzy o dokładnych sekwencjach kontrolnych. (Co więcej, należy argumentować, że nikt nie używa sekwencji SGR ISO 8613-6, ponieważ wszyscy zgadzają się co do błędu polegającego na używaniu średnika jako ogranicznika dla sekwencji RGB SGR kolorów. Standard faktycznie określa dwukropek.)
Jak wspomniano, GNU grep
faktycznie wykazuje niektóre z tych dodatkowych złożoności. Nie konsultuje termcap / terminfo, zapisuje sekwencje kontrolne do emisji i zapisuje odpowiedź na TERM
zmienną środowiskową.
Jego port Linux / Unix ma ten kod , który umożliwia kolorowanie tylko wtedy, gdy TERM
istnieje zmienna środowiskowa, a jej wartość nie jest zgodna z nazwą przewodową dumb
:
int
should_colorize (void)
{
char const * t = getenv („TERM”);
return t && strcmp (t, „głupi”)! = 0;
}
Więc nawet jeśli TERM
tak xterm-mono
, GNU grep
zdecyduje się na emisję kolorów, nawet jeśli inne programy tego vim
nie zrobią.
Jego port Win32 ma ten kod , który umożliwia kolorowanie, gdy TERM
zmienna środowiskowa nie istnieje lub gdy istnieje, a jej wartość nie jest zgodna z nazwą przewodową dumb
:
int
should_colorize (void)
{
char const * t = getenv („TERM”);
powrót ! (t && strcmp (t, „głupi”) == 0);
}
grep
Problemy GNU z kolorem
grep
Kolorystyka GNU jest w rzeczywistości znana. Ponieważ tak naprawdę nie wykonuje właściwej pracy konstruowania danych wyjściowych terminala, a jedynie obwinia w kilku przewodowych sekwencjach sterujących w różnych punktach danych wyjściowych, w próżnej nadziei, że jest to wystarczająco dobre, w rzeczywistości wyświetla nieprawidłowe dane wyjściowe w pewnych okolicznościach.
W tych okolicznościach musi koloryzować coś, co znajduje się na prawym marginesie terminalu. Programy, które prawidłowo wykonują wyjście terminala, muszą uwzględniać automatyczne marginesy automatyczne. Oprócz niewielkiej możliwości, że terminal może ich nie mieć (tzn. auto_right_margin
Pole w terminfo), zachowanie terminali, które mają automatyczne marginesy, często jest zgodne z precedensem DEC VT oczekującego zawijania linii . GNU grep
nie bierze tego pod uwagę, naiwnie oczekując natychmiastowego zawinięcia linii , a jego kolorowe wyjście nie działa .
Kolorowe wydruki nie są prostą sprawą.
Dalsza lektura