Lorsque j'exécute une commande à partir d'un terminal qui imprime une sortie colorée (comme ls
ou gcc
), la sortie colorée est imprimée. D'après ma compréhension, le processus génère en fait des codes d'échappement ANSI et le terminal formate la couleur.
Cependant, si j'exécute la même commande par un autre processus (disons une application C personnalisée) et redirige la sortie vers la propre sortie de l'application, ces couleurs ne persistent pas.
Comment un programme décide-t-il de produire ou non du texte au format couleur? 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:isatty()
.TERM
variable d'environnement doit exister et sa valeur doit correspondre à un enregistrement de base de données.TERMCAP
variable d'environnement. Ainsi, sur certaines implémentations, il existe une deuxième variable d'environnement.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.set_a_foreground
etset_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:isatty()
vérification, de sorte que le programme suppose toujours ou jamais qu'il a un terminal (à colorier) comme sortie. Pour des exemples:ls
a l'--color
option de ligne de commande.ls
examine les variables d'environnementCLICOLOR
(son absence signifie jamais ) etCLICOLOR_FORCE
(sa présence signifie toujours ), ainsi que l'-G
option de ligne de commande.TERM
.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 à laTERM
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
:Donc, même si
TERM
c'est le casxterm-mono
, GNUgrep
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
:grep
Problèmes de GNU avec la couleurgrep
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 . GNUgrep
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
grep --color
msgstr " n'affiche pas la bonne sortie ". FAQ xterm . Île invisible.la source
$TERM
n'explique pas cela. (Votre réponse est intéressante en général, mais je ne pense pas qu'elle réponde à la question ...)La
unbuffer
commande du package attendu dissocie la sortie du premier programme et l'entrée du deuxième programme.Vous l'utiliseriez comme ceci:
Je l'utilise tout le temps avec ansible et un script ctee homebrewed afin que je puisse voir la sortie couleur sur le terminal, tout en laissant le fichier journal avec une sortie normale (non colorisée).
la source