Como verificar se o bash pode imprimir cores

62

Quero saber se há alguma maneira de verificar se meu programa pode gerar saída de terminal usando cores ou não.

Executando comandos como lesse olhando para a saída de um programa que sai usando cores, a saída é exibida incorretamente, como

[ESC[0;32m0.052ESC[0m ESC[1;32m2,816.00 kbESC[0m]

obrigado

Angelo Vargas
fonte

Respostas:

68

A idéia é que meu aplicativo saiba não colorir a saída se o programa não puder imprimir, digamos, registrar a saída de uma tarefa cron em um arquivo, não há necessidade de registrar a saída colorida, mas ao executar manualmente, gosto de ver a saída colorida

Em que idioma você está escrevendo seu aplicativo?

A abordagem normal é verificar se o dispositivo de saída é um tty e, se for, verificar se esse tipo de terminal suporta cores.

Em bash, isso pareceria

# check if stdout is a terminal...
if test -t 1; then

    # see if it supports colors...
    ncolors=$(tput colors)

    if test -n "$ncolors" && test $ncolors -ge 8; then
        bold="$(tput bold)"
        underline="$(tput smul)"
        standout="$(tput smso)"
        normal="$(tput sgr0)"
        black="$(tput setaf 0)"
        red="$(tput setaf 1)"
        green="$(tput setaf 2)"
        yellow="$(tput setaf 3)"
        blue="$(tput setaf 4)"
        magenta="$(tput setaf 5)"
        cyan="$(tput setaf 6)"
        white="$(tput setaf 7)"
    fi
fi

echo "${red}error${normal}"
echo "${green}success${normal}"

echo "${green}0.052${normal} ${bold}${green}2,816.00 kb${normal}"
# etc.

Em C, você precisa digitar muito mais, mas pode obter o mesmo resultado usando o isatty e as funções listadas em man 3 terminfo.

Mikel
fonte
^^ que ^^ era exatamente o que eu estava procurando. Obrigado.
Tim Kennedy
Obrigado pela dica sobre tput. Esta é realmente uma ótima resposta.
AmadeusDrZaius
24

Isso deve ser suficiente:

$ tput colors

tput colors explicou:

Se você olhar a página de manual, perceberá o seguinte:

SYNOPSIS
       tput [-Ttype] capname [parms ... ]

E...

   capname
          indicates the capability from the terminfo database.  When term
          cap  support is compiled in, the termcap name for the capability
          is also accepted.

O termcap colorsestá no banco de dados terminfo, para que você possa solicitá-lo. Se você tiver um status de saída zero, o termcap será compilado. Mas se você tiver algo como:

$ tput unknowntermcap
tput: unknown terminfo capability 'unknowntermcap'
$ echo $?
4

Isso mostra que unknowntermcap não existe. Então, é isso:

$ tput colors
8
$ echo $?
0

Mostra que seu comando estava certo.

Outras maneiras úteis:

  • Em C, você pode usar isatty e ver se é um TTY
  • Veja se é um terminal burro parecendo variável $ TERM

Felicidades

D4RIO
fonte
colorsnão está documentado na tputpágina de manual (!), portanto, devo procurar um número> = 8 no stdout ou um código de retorno 0?
L0b0
Parecia óbvio, mas seu comentário mostra que não é. Estou acrescentando que info (brevemente, cores é uma capacidade de terminfo de banco de dados)
D4RIO
11
A colorscapacidade está documentada no terminfo (5) . Testando usando tput -T dumb colors, tput -T vt220 colors, tput -T linux colors, tput -T xterm colorssugere valores comuns são -1(sem suporte de cor) e 8(8 cores). Observe que isso só se aplica após a verificação do dispositivo de saída como um terminal (por exemplo, [ -t 1 ]ou isatty).
Mikel
Observe que tput colorsretorna o que o banco de dados do terminal local pensa do terminal. Isso pode ou não corresponder ao que o terminal pode realmente fazer, especialmente para um tipo de terminal como o xtermque existe em várias variantes (variando de preto e branco a 256 cores).
Gilles 'SO- stop be evil'
7

A idéia é que meu aplicativo saiba não colorir a saída se o programa não puder imprimir, digamos, registrar a saída de uma tarefa cron em um arquivo, não há necessidade de registrar a saída colorida, mas ao executar manualmente, gosto de ver a saída colorida.

Para este caso de uso, o que os programas costumam fazer (por exemplo, GNU ls ou GNU grep --color=auto) é usar cores se a saída for para um terminal e sem cores caso contrário. Os terminais que não suportam sequências de alteração de cores ANSI são raros o suficiente para que seus usuários substituam a opção padrão. De qualquer forma, verifique se o aplicativo tem uma opção para forçar ou desabilitar as cores.

Em um script de shell, use [ -t 1 ]para testar se a saída padrão é um terminal.

# option processing has set $color to yes, no or auto
if [ $color = auto ]; then
  if [ -t 1 ]; then color=yes; else color=no; fi
fi

Em um programa usando a API C, chame isatty(1).

# option processing has set use_color to 0 for no, 1 for yes or 2 for auto
if (use_color == 2) use_color = isatty(1);
Gilles 'SO- parar de ser mau'
fonte
5

Executando comandos como menos e olhando para a saída de um programa que sai usando cores, a saída é exibida incorretamente, como

[ESC [0; 32m0,052ESC [0m ESC [1; 32m2,816,00 kbESC [0m]

Tente usar less --RAW-CONTROL-CHARS.

Neste exemplo, estou usando o logtool , que imprime a saída usando cores.

Sem --RAW-CONTROL-CHARS:

$ head -20 /var/log/messages | logtool | less
ESC[0mESC[0;37mMar 20 11:43:52ESC[0mESC[1;36m host1ESC[0mESC[0;37m rsyslogd:ESC[0m ^GESC[0;31mlast message repeated 14 timesESC[0mESC[0m

Com --RAW-CONTROL-CHAR (imagine que isso tenha cores bonitas. Além disso, não sei por que isso ^Gestá sendo exibido.):

$ head -20 /var/log/messages | logtool | less --RAW-CONTROL-CHARS
Mar 20 11:43:52 host1 rsyslogd: ^Glast message repeated 14 times
Stefan Lasiewski
fonte
2

Isso seria culpa de lessnão estar definido para interpretar escapes de ANSI; procure Rdentro $LESSOPTS. Quanto a determinar se o sistema sabe que seu terminal pode lidar com cores, tput colorsproduzirá o número de cores que ele suporta ou -1se não suporta cores. (Observe que alguns terminais podem ser usados ​​em xtermvez de xterm-colorcomo descrição do terminal, mas ainda suportam cores.)

geekosaur
fonte
A idéia é que meu aplicativo saiba não colorir a saída se o programa não puder imprimir, digamos, registrar a saída de uma tarefa cron em um arquivo, não há necessidade de registrar a saída colorida, mas ao executar manualmente, gosto de ver a saída colorida.
Angelo Vargas