C'è qualche variabile d'ambiente?
Sì. È la TERM
variabile d'ambiente. Questo perché ci sono diverse cose che vengono utilizzate come parte del processo decisionale.
È difficile generalizzare qui, perché non tutti i programmi concordano su un singolo diagramma di flusso decisionale. In effetti GNU grep
, menzionato nella risposta di M. Kitt, è un buon esempio di valore anomalo che utilizza un processo decisionale alquanto insolito con esiti inaspettati. In termini molto generali, quindi:
- L'output standard deve essere un dispositivo terminale, come determinato da
isatty()
.
- Il programma deve essere in grado di cercare il record per il tipo di terminale nel database termcap / terminfo.
- Così dunque ci deve essere un tipo di terminale a guardare in alto. La
TERM
variabile di ambiente deve esistere e il suo valore deve corrispondere a un record del database.
- È pertanto necessario un database terminfo / termcap. Su alcune implementazioni del sottosistema, è possibile specificare l'ubicazione del database termcap utilizzando una
TERMCAP
variabile di ambiente. Quindi su alcune implementazioni c'è una seconda variabile d'ambiente.
- Il record termcap / terminfo deve indicare che il tipo di terminale supporta i colori. C'è un
max_colors
campo in terminfo. Non è impostato per tipi di terminali che non dispongono effettivamente di funzionalità di colore. In effetti, esiste una convenzione terminfo secondo cui per ogni tipo di terminale colorabile esiste un altro record con -m
o -mono
aggiunto al nome che non indica alcuna capacità di colore.
- Il record termcap / terminfo deve consentire al programma di cambiare colore. Ci sono
set_a_foreground
e set_a_background
campi in terminfo.
È un po 'più complesso del semplice controllo isatty()
. È reso ulteriormente complicato da diverse cose:
- Alcune applicazioni aggiungono opzioni della riga di comando o flag di configurazione che sovrascrivono il
isatty()
controllo, in modo che il programma sia sempre o mai presupponga avere un terminale (colorabile) come output. Per esempio:
- GNU
ls
ha il--color
opzione da riga di comando.
- BSD
ls
esamina le variabili di ambiente CLICOLOR
(il suo significato in assenza mai ) e CLICOLOR_FORCE
(il suo significato in presenza sempre ) e sfoggia anche l' -G
opzione da riga di comando.
- Alcune applicazioni non usano termcap / terminfo e hanno risposte cablate al valore di
TERM
.
- Non tutti i terminali usano sequenze SGR ECMA-48 o ISO 8613-6, che sono leggermente erroneamente denominate "sequenze di fuga ANSI", per cambiare i colori. Il meccanismo termcap / terminfo è infatti progettato per isolare le applicazioni dalla conoscenza diretta delle esatte sequenze di controllo. (Inoltre, c'è da argomentare che nessuno usa sequenze SGR ISO 8613-6, perché tutti concordano sul bug dell'uso di punti e virgola come delimitatore per sequenze SGR di colori RGB. Lo standard specifica in realtà i due punti.)
Come accennato, GNU in grep
realtà mostra alcune di queste complessità aggiuntive. Non consulta termcap / terminfo, fissa le sequenze di controllo da emettere e fissa una risposta alla TERM
variabile d'ambiente.
La porta Linux / Unix ha questo codice , che abilita la colorazione solo quando TERM
esiste la variabile d'ambiente e il suo valore non corrisponde al nome cablatodumb
:
int
should_colorize (vuoto)
{
char const * t = getenv ("TERM");
ritorna t && strcmp (t, "dumb")! = 0;
}
Quindi, anche se il vostro TERM
IS xterm-mono
, GNU grep
deciderà di colori che rilasciano, anche se altri programmi, come vim
non lo faranno.
La porta Win32 ha questo codice , che consente la colorazione sia quando la TERM
variabile di ambiente non esiste o quando esiste e il suo valore non corrisponde al nome cablatodumb
:
int
should_colorize (vuoto)
{
char const * t = getenv ("TERM");
ritorno ! (t && strcmp (t, "dumb") == 0);
}
grep
Problemi di GNU con il colore
grep
La colorazione di GNU è in realtà nota. Poiché in realtà non fa un buon lavoro nella costruzione dell'output del terminale, ma bensì solo in alcune sequenze di controllo cablate in vari punti del suo output nella vana speranza che ciò sia abbastanza buono, in realtà mostra un output errato in determinate circostanze.
Queste circostanze sono dove deve colorare qualcosa che si trova sul margine destro del terminale. I programmi che eseguono correttamente l'output del terminale devono tenere conto dei margini automatici automatici. Oltre alla leggera possibilità che il terminale non possa averli (vale a dire il auto_right_margin
campo in terminfo), il comportamento dei terminali che hanno margini a destra automatici spesso segue il precedente DEC VT dell'involucro di linea in sospeso . GNU grep
non tiene conto di questo, ingenuamente si aspetta un avvolgimento di riga immediato e il suo output colorato va storto.
L'output a colori non è una cosa semplice.
Ulteriori letture