Como verificar se o bash pode imprimir cores

54

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

Executando comandos como less e observando a saída de um programa que produz usando cores, a saída é exibida incorretamente, como

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

Obrigado

    
por Angelo Vargas 23.03.2011 / 15:44

6 respostas

59

The idea is for my application to know not to color the output if the program can't print, say, logging output from through a cron job to a file, no need to log colored output, but when running manually, i like to view the output colored

Em que idioma você está escrevendo sua inscrição?

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

Em bash , parece que

# 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 isatty e as funções listadas em man 3 terminfo .

    
por 25.03.2011 / 01:04
19

Isso deve ser suficiente:

$ tput colors

tput cores explicadas:

Se você olhar para a manpage, notará isso:

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 colors está no banco de dados terminfo, portanto, você pode solicitá-lo. Se você tem um status de saída zero, então o termcap é 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 formas úteis:

  • Em C, você pode usar apenas isatty e ver se é um TTY
  • Veja se é um terminal idiota procurando uma variável $ TERM

Felicidades

    
por 23.03.2011 / 15:56
7

The idea is for my application to know not to color the output if the program can't print, say, logging output from through a cron job to a file, no need to log colored output, but when running manually, i like to view the output colored.

Para este caso de uso, o que os programas normalmente fazem (por exemplo, GNUls ou GNUpsp com --color=auto ) é usar cores se a saída estiver indo para um terminal e nenhuma outra cor. Os terminais que não suportam seqüências de mudança de cores ANSI são tão raros que é aceitável fazer com que seus usuários substituam a opção padrão. Em qualquer caso, certifique-se de que seu aplicativo tenha uma opção para ativar ou desativar 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

De 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);
    
por 24.03.2011 / 21:37
4

Running commands like less and looking at the output from a program that outputs using colors, the output is displayed wrong, like

[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 está em cores bonitas. Além disso, não sei por que ^G está sendo exibido.):

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

Isso seria culpa de less não estar definido para interpretar escapes ANSI; procure por R em $LESSOPTS . Para determinar se o sistema sabe que seu terminal pode lidar com cores, tput colors produzirá o número de cores que ele suporta ou -1 se ele não suportar cores. (Observe que alguns terminais podem usar xterm em vez de xterm-color como sua descrição do terminal, mas ainda suportam cores.)

    
por 23.03.2011 / 15:51
1

Se você quiser adicionar cor à saída, mas somente quando as cores forem suportadas, você pode simplesmente usar tput . link

    
por 23.03.2011 / 17:42