Y a-t-il une variable d'environnement?
Oui. C'est la TERMvariable d'environnement. En effet, plusieurs éléments sont utilisés dans le cadre du processus de décision.
Il est difficile de généraliser ici, car tous les programmes ne s'entendent pas sur un seul organigramme de décision. En fait, GNU grep, mentionné dans la réponse de M. Kitt, est un bon exemple de valeur aberrante qui utilise un processus de décision quelque peu inhabituel avec des résultats inattendus. En termes très généraux, donc:
- La sortie standard doit être un périphérique terminal, comme déterminé par
isatty().
- Le programme doit pouvoir rechercher l'enregistrement du type de terminal dans la base de données termcap / terminfo.
- Il doit donc y avoir un type de terminal à rechercher. La
TERMvariable d'environnement doit exister et sa valeur doit correspondre à un enregistrement de base de données.
- Il doit donc y avoir une base de données terminfo / termcap. Sur certaines implémentations du sous-système, l'emplacement de la base de données termcap peut être spécifié à l'aide d'une
TERMCAPvariable d'environnement. Ainsi, sur certaines implémentations, il existe une deuxième variable d'environnement.
- L'enregistrement termcap / terminfo doit indiquer que le type de terminal prend en charge les couleurs. Il y a un
max_colorschamp dans terminfo. Il n'est pas défini pour les types de terminaux qui n'ont pas réellement de capacités de couleur. En effet, il existe une convention terminfo selon laquelle pour chaque type de terminal à colorier, il existe un autre enregistrement avec -mou -monoajouté au nom qui n'indique aucune capacité de couleur.
- L'enregistrement termcap / terminfo doit permettre au programme de changer les couleurs. Il y a des champs
set_a_foregroundet set_a_backgrounddans terminfo.
C'est un peu plus complexe que de simplement vérifier isatty(). Il est rendu encore plus compliqué par plusieurs choses:
- Certaines applications ajoutent des options de ligne de commande ou des indicateurs de configuration qui remplacent la
isatty()vérification, de sorte que le programme suppose toujours ou jamais qu'il a un terminal (à colorier) comme sortie. Pour des exemples:
- GNU
lsa l' --coloroption de ligne de commande.
- BSD
lsexamine les variables d'environnement CLICOLOR(son absence signifie jamais ) et CLICOLOR_FORCE(sa présence signifie toujours ), ainsi que l' -Goption de ligne de commande.
- Certaines applications n'utilisent pas termcap / terminfo et ont des réponses câblées à la valeur de
TERM.
- Tous les terminaux n'utilisent pas les séquences ECMA-48 ou ISO 8613-6 SGR, qui sont légèrement mal nommées "séquences d'échappement ANSI", pour changer les couleurs. Le mécanisme termcap / terminfo est en fait conçu pour isoler les applications de la connaissance directe des séquences de contrôle exactes. (De plus, il y a un argument à faire valoir que personne n'utilise les séquences SGR ISO 8613-6, parce que tout le monde est d'accord sur le bug de l'utilisation du point-virgule comme délimiteur pour les séquences SGR de couleur RVB. La norme spécifie en fait deux points.)
Comme mentionné, GNU grepprésente en fait certaines de ces complexités supplémentaires. Il ne consulte pas termcap / terminfo, câblé les séquences de contrôle à émettre et câblant une réponse à la TERMvariable d'environnement.
Le port Linux / Unix de celui-ci a ce code , qui permet la coloration uniquement lorsque la TERMvariable d'environnement existe et que sa valeur ne correspond pas au nom câblé dumb:
int
should_colorize (void)
{
char const * t = getenv ("TERM");
retourne t && strcmp (t, "idiot")! = 0;
}
Donc, même si TERMc'est le cas xterm-mono, GNU grepdécidera d'émettre des couleurs, même si d'autres programmes comme celui- vimci ne le feront pas.
Le port Win32 de celui-ci a ce code , qui permet la coloration soit lorsque la TERMvariable d'environnement n'existe pas ou lorsqu'elle existe et que sa valeur ne correspond pas au nom câblé dumb:
int
should_colorize (void)
{
char const * t = getenv ("TERM");
revenir ! (t && strcmp (t, "idiot") == 0);
}
grepProblèmes de GNU avec la couleur
grepLa colorisation de GNU est en fait notoire. Parce qu'il ne fait pas vraiment un bon travail de construction de la sortie du terminal, mais qu'il blâme plutôt dans quelques séquences de contrôle câblées à divers points de sa sortie dans le vain espoir que cela soit assez bon, il affiche en fait une sortie incorrecte dans certaines circonstances.
Dans ces circonstances, il doit coloriser quelque chose qui se trouve à la marge droite du terminal. Les programmes qui font correctement la sortie du terminal doivent tenir compte des marges droites automatiques. En plus de la légère possibilité que le terminal ne les ait pas (à savoir le auto_right_marginchamp dans terminfo), le comportement des terminaux qui ont des marges droites automatiques suit souvent le précédent DEC VT du retour à la ligne en attente . GNU grepne tient pas compte de cela, s'attendant naïvement à un retour à la ligne immédiat , et sa sortie colorée va mal.
La sortie couleur n'est pas une chose simple.
Lectures complémentaires