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:
- A saída padrão deve ser um dispositivo terminal, conforme determinado por
isatty()
.
- O programa deve poder procurar o registro para o tipo de terminal no banco de dados termcap / terminfo.
- Portanto, deve haver um tipo de terminal para procurar. A
TERM
variável de ambiente deve existir e seu valor deve corresponder a um registro do banco de dados.
- Portanto, deve haver um banco de dados terminfo / termcap. Em algumas implementações do subsistema, o local do banco de dados termcap pode ser especificado usando uma
TERMCAP
variável de ambiente. Portanto, em algumas implementações, há uma segunda variável de ambiente.
- O registro termcap / terminfo deve indicar que o tipo de terminal suporta cores. Há um
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.
- O registro termcap / terminfo deve fornecer o caminho para o programa alterar as cores. Existem
set_a_foreground
e set_a_background
campos no terminfo.
É um pouco mais complexo do que apenas checar isatty()
. É complicado ainda mais por várias coisas:
- Alguns aplicativos adicionam opções de linha de comando ou sinalizadores de configuração que substituem a
isatty()
verificação, para que o programa sempre ou nunca assuma que ele possui um terminal (colorido) como saída. Por exemplo:
- O GNU
ls
tem a --color
opção de linha de comando.
- O BSD
ls
analisa as variáveis de ambiente CLICOLOR
(sua ausência significa nunca ) e CLICOLOR_FORCE
(sua presença significa sempre ) e também exibe a -G
opção de linha de comando.
- Alguns aplicativos não usam termcap / terminfo e têm respostas conectadas ao valor de
TERM
.
- Nem todos os terminais usam sequências ECMA-48 ou ISO 8613-6 SGR, que são levemente denominadas "sequências de escape ANSI", para alterar as cores. O mecanismo termcap / terminfo é de fato projetado para isolar aplicativos do conhecimento direto das seqüências exatas de controle. (Além disso, existe um argumento de que ninguém usa sequências SGR ISO 8613-6, porque todos concordam com o erro de usar ponto e vírgula como delimitador para sequências SGR de cores RGB. O padrão realmente especifica dois pontos.)
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 hardware dumb
:
int
should_colorize (vazio)
{
char const * t = getenv ("TERM");
retornar t && strcmp (t, "burro")! = 0;
}
Portanto, mesmo que você TERM
seja xterm-mono
, o GNU grep
decidirá emitir cores, mesmo que outros programas como esse vim
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 hardware dumb
:
int
should_colorize (vazio)
{
char const * t = getenv ("TERM");
Retorna ! (t && strcmp (t, "burro") == 0);
}
grep
Problemas do GNU com cores
A 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 GNU grep
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