Y a-t-il une variable d'environnement?
Oui. C'est la TERM
variable 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
TERM
variable 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
TERMCAP
variable 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_colors
champ 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 -m
ou -mono
ajouté 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_foreground
et set_a_background
dans 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
ls
a l' --color
option de ligne de commande.
- BSD
ls
examine les variables d'environnement CLICOLOR
(son absence signifie jamais ) et CLICOLOR_FORCE
(sa présence signifie toujours ), ainsi que l' -G
option 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 grep
pré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 TERM
variable d'environnement.
Le port Linux / Unix de celui-ci a ce code , qui permet la coloration uniquement lorsque la TERM
variable 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 TERM
c'est le cas xterm-mono
, GNU grep
décidera d'émettre des couleurs, même si d'autres programmes comme celui- vim
ci ne le feront pas.
Le port Win32 de celui-ci a ce code , qui permet la coloration soit lorsque la TERM
variable 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);
}
grep
Problèmes de GNU avec la couleur
grep
La 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_margin
champ 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 grep
ne 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