Como exibir cores no terminal

Quer exibir os textos com cores, negritos, itálicos, underline etc? Entendendo algumas regras e códigos, fica bem mais fácil do que parece. Entenda como exibir cores no seu terminal com a clareza de quem sabe o que está fazendo.

Tempo estimado de leitura: 8 minutos

Depois que você já entendeu como utilizar as cores no seu terminal, fica super fácil de usar. Será quase que indispensável colorir seus códigos shell script!

Procurei mastigar bem esse o conteúdo da forma mais objetiva possível. Espero que seja um bom ponto de partida para você sair por aí pintando tudo, hehe. Vamos por partes.

Código de escape

Antes de mais nada, é importante saber que para ativar a cor deve-se utilizar um código de escape que chame pela função de coloração. O código é ESC[m.

O código pode ser chamado de várias maneiras. De acordo com a tabela ascii em man ascii:

Oct   Dec   Hex   Char
-------------------------------
033   27    1B    ESC (escape)

Pessoalmente, gosto de chamar o ESC pelo octal \033. Nas novas versões do bash, também dá pra chamar por \e, mas o uso do hex ou octal te dará menos dor de cabeça. Detalhe: o decimal geralmente não funciona!

Atenção: No MacOS, a última versão do bash é muito antiga, 3.2.57. Recomendo atualizar para a versão 5 com brew.

Portanto, chame a função de formação de estilo da seguinte forma (não colocamos nenhum estilo/cor ainda):

echo -e "\033[m" Texto pronto para receber cores. Escape em octal
echo -e "\x1b[m" Outro texto sem cores. Escape em hexadecimal

Formatação

Então vamos começar a colorir. Basicamente temos que lidar com 3 características da formatação. São elas:

  1. Efeito de decoração do texto
  2. Cor do texto (foreground)
  3. Cor do fundo (background)

Cada uma dessas características tem um código único, que será visto a seguir.

Decoração

A tabela abaixo deverá funcionar para todos os modos de cores, mas nem sempre para todos os terminais. Cada terminal tem suas particularidades.

Código  | Descrição
------- | -----------
0       | Reset/Normal
1       | Bold text
2       | Dim (escurece)
3       | Italics
4       | Underlined text
5       | Blink
7       | Reverse
8       | Hidden
9       | Tachado

Aplique o código entre ESC[ e m.

Depois de cada trecho de texto colorido, dê um reset (0) com ESC[0m, ou simplesmente omita qualquer código, deixando ESC[m.

echo -e "\033[1m" Com negrito. "\033[m" Texto normal.  
echo -e "\033[1m" Com negrito. "\033[m" Texto normal.  

E também é possível combinar formatações, separando os códigos com o sinal ;

echo -e "\033[1;3m" Negrito e itálico. "\033[0m" Texto normal.  

Usando printf, a sintaxe muda um pouco, mas também é simples. Ele é dividido em 2 partes: formatação, onde você define detalhes sobre o tipo (texto, número, códigos de cores etc) e os argumentos, onde você insere as informações que receberão a formatação. Veja nos exemplos:

printf '\033[1;3m %s \033[0m' "Texto decorado."
printf '\033[48;2;255;255;255;38;2;255;0;255m %3d \033[0m %s \033[1;4;31m %3d \033[0m' 100 "Texto sem cor:" 3

Nota: Para fins didáticos, as formatações do printf estão entre aspas simples ‘ ‘, e os argumentos estão logo em seguida.

Modos de cores

Aí o negócio fica mais complexo, já que cada terminal pode ler de um jeito. De um terminal para outro, poderá haver suporte para mais ou menos modos de cores. No MacOS, o iTerm 2 é uma boa pedida, inclusive com divisões de janelas, o que é bem interessante para quem passa o dia trabalhando no terminal. Entretanto, o Terminal padrão do MacOS não deve te oferecer impeditivos para este assunto. Um colega pacientemente montou esta tabelinha interessante de compatibilidades.

São 4 modos de cores:

  1. ASCII puro
  2. ANSI escape codes: 16 códigos de cores com negrito/itálico e fundo
  3. 256 cores: 216 cores + 16 ANSI + 24 cinza (cores 24-bit)
  4. 24-bit true color: “8 8 8” ou “11111111 11111111 11111111” cores (16 milhões de cores)

Modo 8/16 cores

Como dito acima, cada cor tem um código único. Neste modo, as cores que vão alterar o texto tem código “3x” e “9x” e as cores que alteram o fundo começam com “4x” e “10x”. Veja a tabela

Color           | Foreground Code   | Background Code
--------------- | ----------------- | --------------
Default Color   | 39                | 49
Black           | 30                | 40
Red             | 31                | 41
Green           | 32                | 42
Yellow          | 33                | 43
Blue            | 34                | 44
Magenta         | 35                | 45
Cyan            | 36                | 46
Light Gray      | 37                | 47
Gray            | 90                | 100
Light Red       | 91                | 101
Light Green     | 92                | 102
Light Yellow    | 93                | 103
Light Blue      | 94                | 104
Light Magenta   | 95                | 105
Light Cyan      | 96                | 106
White           | 97                | 107

Para este modo, a sintaxe do código pode seguir este padrão ESC[E;F;Bm, sendo que E podem ser vários códigos de decoracao.

Código  | Descrição
------- | ---------
ESC[    | Sequência de escape para iniciar cores
E       | Código de efeito.
F       | Código da cor do texto; um valor de 30 à 37.
B       | Código de cor de fundo; um valor de 40 à 47.
m       | Representa o fim da sequência de cores.

E ordem do código também não importa.

Exemplos:

echo -e "\033[1;92;104m Texto verde claro em negrito com fundo azul claro \033[m"
echo -e "\033[5;3;31;107m Texto vermelho, piscante, itálico com fundo branco \033[m"
echo -e "\033[4;90m Texto cinza, sobrescrito\033[m"
echo -e "\033[1;5m Bold+Blink \033[0m"
echo -e "\033[1;4;31m Bold+Underline+Red \033[0m"

O código de cores também pode entrar em variáveis:

# Seta cores
RED='\033[0;31m'
HEADER='\033[95m'
OKBLUE='\033[94m'
OKGREEN='\033[92m'
WARNING='\033[93m'
FAIL='\033[91m'
BOLD='\033[1m'
UNDERLINE='\033[4m'
ENDC='\033[0m'

echo -e "${RED}LINHA COM CORES${ENDC}"
echo -e "${HEADER}LINHA COM CORES${ENDC}"
echo -e "${OKBLUE}LINHA COM CORES${ENDC}"
echo -e "${OKGREEN}LINHA COM CORES${ENDC}"
echo -e "${WARNING}LINHA COM CORES${ENDC}"
echo -e "${FAIL}LINHA COM CORES${ENDC}"
echo -e "${BOLD}LINHA COM CORES${ENDC}"
echo -e "${UNDERLINE}LINHA COM CORES${ENDC}"

Modo 88/256 cores

Para ativar o modo de 88/256 cores para texto, fundo ou ambos, é um pouco diferente. A combinação de códigos é com 2 sequências diferentes:

  1. Para fixar a cor do texto, o código é 38;5;{0..255}, onde {0..255} é uma das 256 cores
  2. Para fixar a cor no fundo, o código é 48;5;{0..255}

Veja a lista completa das 256 cores e suas combinações com cor de texto/fundo executando este shell script:

#!/bin/bash

# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.

for fgbg in 38 48 ; do # Foreground / Background
    for color in {0..255} ; do # Colors
        # Display the color
        printf "\e[${fgbg};5;%sm  %3s  \e[0m" $color $color
        # Display 6 colors per lines
        if [ $((($color + 1) % 6)) == 4 ] ; then
            echo # New line
        fi
    done
    echo # New line
done

Neste caso, precisa seguir ordem de combinação do trio, diferente do modo 8/16 cores acima. Mas tanto faz colocar o background antes do foreground ou vice-versa. Só não pode fazer algo como 5;{0..255};38, senão vai dar ruim.

Veja como fica a combinação de cores de texto, fundo e uma decoração:

# Recapitulando:
# ESC[...m <- identifica o uso de cor
# \033 <- escape
# 38;5;cor <- Cor do texto
# 48;5;cor <- Cor do fundo
# 0 a 9 <- estilo

echo -en "\033[38;5;135;48;5;114;3m Fundo verde e texto rosa itálico \033[m"
echo -en "\033[48;5;135;38;5;235;1m Fundo rosa e texto preto negrito \033[m"

Modo 24-bit true color (16 milhões de cores)

A sintaxe para uso do modo 24-bit não é muito diferente da anterior. O detalhe aqui é a presença do R;G;B:

ESC[{38|48};2;${red};${green};${blue}m

Exemplos:

# Cor do texto
echo -e "\033[38;2;255;0;255mTRUECOLOR\033[0m\n";

# Cor do fundo
echo -e "\033[48;2;255;255;255mTRUECOLOR\033[0m\n";

# Cor do texto e do fundo
echo -e "\033[48;2;255;255;255;38;2;255;0;255mTRUECOLOR\033[0m\n";

# Cor texto, fundo e estilo
echo -e "\033[48;2;255;255;255;38;2;255;0;255;3mTRUECOLOR\033[0m\n"

Veja que interessante a aplicação destes degradê de fundo.

for i in {16..20} {20..16} ; do echo -e "\033[48;5;${i};1m :o) \033[0m" ; done
for i in {22..27} {27..22} ; do echo -en "\033[48;5;${i};1m \033[0m" ; done


Considerações finais

Como você pode ver, não é complicado. É só saber utilizar o modo de cores correto e acertar o código de escape.

Para este artigo, usamos bastante o comando echo, com seu argumento -e, que permite o uso de caracteres especiais com escape. Mas você também pode usar o printf sem problema algum, caso precise das funções avançadas dessa ferramenta.

Para saber mais sobre o echo, leia o manual do comando que é bem fácil de compreender.

man echo

O printf é um pouco mais complexo, mas muito interessante. Vale a pena.

man printf

Espero que tenha gostado.

Dúvidas? Deixe um comentário.

Veja também

  • tput http://linuxcommand.org/lc3_adv_tput.php para manipulações do terminal
  • Seção cores amparada pelos “bash tips” de https://misc.flogisoft.com/bash/tip_colors_and_formatting
  • https://gist.github.com/XVilka/8346728

Sobre o autor

Respostas de 6

    1. Fala, Éder!
      Cada terminal tem um jeito de lidar com a tipografia e tamanho da fonte, não é algo que você seta no shell.
      Eu gosto muito do iTerm2 para MacOS e Terminator para Linux, dá uma olhadinha neles.
      Abração!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Mais artigos

bureau-it.com