Quando executo um comando de um terminal que imprime saída colorida (como ls
ou gcc
), a saída colorida é impressa. Pelo que entendi, o processo está realmente emitindo códigos de escape ANSI e o terminal formata a cor.
No entanto, se eu executar o mesmo comando por outro processo (por exemplo, um aplicativo C personalizado) e redirecionar a saída para a própria saída do aplicativo, essas cores não persistirão.
Como um programa decide se deve ou não produzir texto com formato de cor? Existe alguma variável de ambiente?
Sim. É a
TERM
variável de ambiente. Isso ocorre porque existem várias coisas que são usadas como parte do processo de decisão.É difícil generalizar aqui, porque nem todos os programas concordam com um único fluxograma de decisão. De fato
grep
, o GNU , mencionado na resposta de M. Kitt, é um bom exemplo de um outlier que usa um processo de decisão um tanto incomum, com resultados inesperados. Em termos muito gerais, portanto:isatty()
.TERM
variável de ambiente deve existir e seu valor deve corresponder a um registro do banco de dados.TERMCAP
variável de ambiente. Portanto, em algumas implementações, há uma segunda variável de ambiente.max_colors
campo no terminfo. Não está definido para tipos de terminais que realmente não possuem recursos de cores. De fato, existe uma convenção terminfo de que para cada tipo de terminal colorido existe outro registro com-m
ou-mono
anexado ao nome que não indica capacidade de cores.set_a_foreground
eset_a_background
campos no terminfo.É um pouco mais complexo do que apenas checar
isatty()
. É complicado ainda mais por várias coisas:isatty()
verificação, para que o programa sempre ou nunca assuma que ele possui um terminal (colorido) como saída. Por exemplo:ls
tem a--color
opção de linha de comando.ls
analisa as variáveis de ambienteCLICOLOR
(sua ausência significa nunca ) eCLICOLOR_FORCE
(sua presença significa sempre ) e também exibe a-G
opção de linha de comando.TERM
.Como mencionado, o GNU
grep
realmente exibe algumas dessas complexidades adicionais. Ele não consulta termcap / terminfo, conecta as seqüências de controle a serem emitidas e conecta uma resposta àTERM
variável de ambiente.A porta Linux / Unix possui esse código , que permite a colorização somente quando a
TERM
variável de ambiente existe e seu valor não corresponde ao nome do hardwaredumb
:Portanto, mesmo que você
TERM
sejaxterm-mono
, o GNUgrep
decidirá emitir cores, mesmo que outros programas como essevim
não o façam.A porta Win32 contém esse código , que permite a coloração quando a
TERM
variável de ambiente não existe ou quando existe e seu valor não corresponde ao nome do hardwaredumb
:grep
Problemas do GNU com coresA coloração
grep
do GNU é realmente notória. Como na verdade ele não faz um bom trabalho na construção da saída do terminal, mas apenas culpa algumas seqüências de controle conectadas em vários pontos de sua saída, na vã esperança de que isso seja bom o suficiente, na verdade exibe uma saída incorreta em determinadas circunstâncias.É nessas circunstâncias que é necessário colorir algo que está na margem direita do terminal. Os programas que executam corretamente a saída do terminal devem contabilizar as margens direitas automáticas. Além da pequena possibilidade de o terminal não os ter (por exemplo, o
auto_right_margin
campo no terminfo), o comportamento dos terminais que possuem margens direitas automáticas geralmente segue o precedente DEC VT de quebra de linha pendente . O GNUgrep
não responde por isso, ingenuamente esperando quebra automática de linha , e sua saída colorida dá errado.Saída colorida não é uma coisa simples.
Leitura adicional
grep --color
não mostra a saída correta ". xterm FAQ . Ilha Invisível.fonte
$TERM
não explica isso. (A sua resposta é interessante em geral, mas eu não acho que aborda a questão ...)O
unbuffer
comando do pacote expectável desacopla a saída do primeiro programa e a entrada para o segundo programa.Você usaria assim:
Eu usá-lo o tempo todo com ansible e uma Homebrewed ETEc roteiro para que eu possa ver a saída de cores no terminal, deixando o arquivo de log com saída normal (não-colorizado).
fonte