Sequências de escape ANSI

A forma mais elementar de se controlar a exibição de caracteres no terminal, seja vídeo ou impresso é usando os códigos de escape ANSI que se tornaram padrão nos anos 1970 para tentar organizar o caos que devia ser com cada fabricante de computador criando seus próprios códigos.

Estas sequências correspondem a usar uma tecla com o carácter “ESCAPE” seguido de um código que, após ser interpretada pelas bibliotecas termcap, terminfo e demais utilitários como o tput, exibiam não só um símbolo na tela, mas também afetava a exibição de dados de alguma forma.

Dentre as inúmeras sequências de escape existentes, há aquelas que permitem posicionar o cursor na tela, ou que emitem um beep, e mesmo destacam o caracter com negrito, itálico, sublinhado, riscado, alteram a cor de frente, do fundo etc.

A página na Wikipedia sobre sequencias de escape ANSI tem um histórico e uma lista com os caracteres e a sequencias (recomendo a leitura para quem quiser se aprofundar no assunto).

Um pouco do conceito

Para usarmos uma sequência de escape nós usaremos o carácter “ESC” seguido de um “[” e a sequência ANSI correspondente.

O carácter “ESC” ou “caracter escape” não possui um símbolo visual e nem mesmo uma tecla no teclado[*], portanto se você olhou para o teclado, perdeu seu tempo 🙂 .

O caracter “ESC” costuma ser representado pelos seus códigos ASCII em octal (\033), hexadecimal (\x1B), decimal (27), expressão “ESC”, pelo símbolo “^[” ou ainda “\e”. É importante saber disso pois em alguns sistemas/ferramentas você deverá usar apenas uma destas formas.

[*]obs: Na verdade a tecla ESC existe sim, e é exatamente aquela que você olhou, mas ela não funciona mais como nos tempos antigos. Hoje em dia ela serve para cancelar uma ação, ou fechar um aviso por exemplo.

Para usarmos estas sequências nós as incluiremos no meio das nossas mensagens de texto para serem exibidas pelos tradicionais comandos de exibição de caracter (“echo”, “print”, “printf”, “cout” etc).

Esteja atento que algumas linguagens suportarão apenas uma representação do caracter de escape. Seja literal, seja em octal ou hexadecimal. Vermos isso nos exemplos.

Exemplo 1: limpar a tela

Para obtermos nossa sequência de escape, nós então usaremos o caracter “ESC” seguido de um “[” e a sequência ANSI correspondente, como nos exemplos abaixo a sequência de escape para limpar a tela do seu terminal:

\e[1J
\033[1J
\0x1b[1J

Note ai que eu usei o caracter ESC, representado respectivamente pelos “\e” (literal), \033 (octal) e 0x1b (hexadecimal), seguido do caracter “[” e então o código de escape desejado (“1J”).

Exibir esta sequencia na sua tela causará o mesmo efeito que usar o comando “clear”, “CLS”, pressionar “CTRL+L”, ou seja lá qual o comando correspondente a isso em seu sistema operacional, ou seja, irá limpar todo o seu conteúdo posicionando o cursor no canto superior esquerdo.

Veja então como usá-la no shell “sh”, no “Bash” e no “Python”:

sh$ echo "\e[1J"
bash$ echo -e "\e[1J"
python>>> print("\x1B[1J")

Note que no Python eu usei a representação em hexadecimal (\x1b) ao invés da literal.

Uma dica adicional sobre estas três linguagens é que todas aceitam o formato octal “\033[“, então se quiser algo “mais padronizado” (ao menos entre estas três) use o octal.

Vou me limitar apenas a estes ambientes, mas esteja a vontade a testar na linguagem de sua preferência.

Exemplo 2: Alterar a cor dos caracteres (3/4bits)

Há duas sequências padronizadas para alterarmos as cores dos caracteres no terminal.

A primeira, que vemos agora, usa a sequencia “\e[codm“, onde “cod” é o código numérico da cor entre 30-39, para alterar a cor do caracter; ou entre 40-49 para alterar a cor do fundo.

Tomando como referência a tabela de cores de 3/4bits, abaixo, basta somar 30 ou 40 ao número da cor desejada.

Por exemplo, a cor azul é o número 4 (vide a tabela na seção seguinte), para escrevermos mensagens com as letras exibidas na cor azul então teriamos que usar a sequencia “\e[34m“. Já se eu quisesse usar a mesma cor azul como fundo dos caracteres, eu usaria a sequencia “\e[44m“.

Experimente usando o “sh” digitar o comando abaixo:

echo "\e[34mTexto em cor azul"

AVISO: Se quiser testar o exemplo acima no Bash, não esqueça do “-e”, em outras linguagens use o comando de exibição adequado, ou as cores não serão alteradas.

Se quiser um exemplo mais completo experimente este abaixo:

echo "\e[30mPRETO \e[31mVERMELHO \e[32mVERDE \e[33mAMARELO \e[34mAZUL \e[35mMAGENTA \e[36mCIANO \e[37mBRANCO \e[39mNORMAL"

Faça testes alterando a cor do fundo também (lembrando de somar 40 e não 30 ao número da cor).

echo "\e[42mAviso com fundo verde"

Em um outro exemplo mais elaborado poderemos alterar as cores dos caracteres e do fundo com o seguinte código:

echo "\e[31;44mTexto em vermelho sobre fundo Azul"

Neste último caso há uma vantagem no uso deste método que é a capacidade de mudar as cores apenas as separando com um “;”.

Códigos de cores com 3/4 bits

O texto sobre códigos de escape ANSI na Wikipedia é uma excelente fonte com bastante detalhamento, mas para você não ter que ir e vir de uma página para outra, segue a lista de cores resumida:

  • 0 = Preto
  • 1 = Vermelho
  • 2 = Verde
  • 3 = Amarelo
  • 4 = Azul
  • 5 = Magenta
  • 6 = Ciano
  • 7 = Branco
  • 8 = reservado
  • 9 = Cor Padrão

Atributos extras de formatação

Nós podemos ainda usar tons de cores mais claros somando 90 para as letras ou 100 para o fundo, ao invés de 30 e 40 como fizemos até aqui.

Compare a saída do exemplo anterior com esta daqui.

echo "\e[31;44mTexto em vermelho sobre fundo Azul"

Por fim, uma curiosidade. Se você não somar 30/90 para cor de frente e nem 40/100 para a cor de fundo, os números de 0 a 9 simples possuem outros significados, como segue:

  • 0 = Reset ou Normal
  • 1 = Negrito ou Alta intensidade
  • 2 = Claro ou Baixa intesidade
  • 3 = Itálico
  • 4 = Sublinhado
  • 5 = Piscante lento
  • 6 = Piscante rápido
  • 7 = Reverso
  • 8 = oculto
  • 9 = Riscado

Execute como exemplo a sequência abaixo exibe o texto em itálico, após limpar a tela (perceba o uso de ambas as sequencias de espace):

echo "\e[1J\e[3mTítulo em itálico"

Exemplo 3: Alterar cores de caracteres (8 bits)

Se 7 cores é muito pouco para o seu script, você pode usar a paleta de 8 bits contendo 256 cores.

As sequências de escape para alterar a cor da letra é “\e[38;5;codm“, enquanto para alterar a cor do fundo é “\e[48;5;codm“.

Onde “cod” é o código da cor de 0 até 255, dividido em 4 grupos:

  • 0 – 7 – As mesmas cores da paleta de 3 bits normal
  • 8 – 15 – As mesmas cores da paleta de 3 bits mais claras
  • 16 – 231 – São 216 cores
  • 232-255 – São 24 tons de cinza iniciando no preto e terminando em branco

Seguem então dois exemplos exibindo uma mensagem em cor amarela sobre um fundo laranja e outra em tons de cinza

echo -e "\e[38;5;220m\e[48;5;130m Mensagem amarela sobre fundo laranja \e[0m"
echo -e "\e[38;5;237m\e[48;5;250m Mensagem com sobretons de cinza \e[0m"

Note que em ambos os exemplos eu usei três sequências de escape. A primeira altera a cor da letra, a segunda a cor do fundo e a última, já no final da mensagem para voltar as cores normais do ambiente.

Função exibir as cores

Se você começar a usar o exemplo acima em suas rotinas, em pouco tempo você sentirá falta de uma exibição de exemplo das cores para melhor escolha dos tons.

Particularmente, eu mantenho uma função salva no meu ~/.bashrc com um código parecido com este abaixo:

function cor256_exemplos() {
    for (( i=0 ; i<256 ; i++ )); do
        c="   ";
        if (( i == 0 )); then echo "8 Cores básicas"; fi
        if (( i == 8 )); then echo -e "\n8 Cores claras"; fi
        if (( i == 16 )); then echo -e "\n216 cores"; fi
        if (( i == 232 )); then echo -e "\n24 tons de cinza"; fi
        if (( i > 9 )); then c="  "; fi
        if (( i > 99 )); then c=" "; fi
        echo -ne "\e[48;5;${i}m[$c$i ]\e[0m"
    done
}

Com esta função salva no .bashrc, ou outro arquivo de inicialização do seu shell, todas as vezes que uma nova sessão for iniciada, ela estará carregada e pronta para ser invocada.

E cada vez que você a invocar, digitando o seu nome, uma tabela com todas as cores será exibida na sua tela exibindo as cores e seus códigos numéricos.

Exemplo 4: Cores em 24 bits

Honestamente eu acho isso um exagero para scripts em modo texto, mas não serei eu quem vou dizer que você não pode usar as mais de 16 milhões de cores disponíveis no seu terminal.

Dito isso, veja abaixo que há três formas RGB, CMY e CMYK, como se vê abaixo, mas embora documentados, eu não encontrei nenhum ambiente onde os modelos CMY e CMYK funcionassem corretamente, então vou deixar apenas exemplos usando RGB.

Sequência para cores RGB

As sequências de escape para alterar a cor da letra é “\e[38;2;R;G;Bm“, enquanto para alterar a cor do fundo é “\e[48;2;R;G;Bm“, onde R, G e B são números entre 0 e 255 representando respectivamente a quantidade cor Vermelha (R), Verde (G) e Azul (B).

E ao contrário do padrão de 256 cores, usando RGB a quantidade é grande demais para para gerarmos uma tabela, então minha recomendação é que se teste os tons por experimentação ou usando alguma ferramenta de mistura de cores.

Sequência para cores CMY

As sequências de escape para alterar a cor da letra é “\e[38;3;C;M;Ym“, enquanto para alterar a cor do fundo é “\e[48;3;C;M;Ym“, onde C, M e Y são números entre 0 e 255 representando respectivamente a quantidade cor Ciano (C), Magenta (M) e Amarelo (Y).

Sequência para cores CMYK

As sequências de escape para alterar a cor da letra é “\e[38;3;C;M;Y;Km“, enquanto para alterar a cor do fundo é “\e[48;3;C;M;Y;Km“, onde C, M, Y e K são números entre 0 e 255 representando respectivamente a quantidade cor Ciano (C), Magenta (M), Amarelo (Y) e Preto (K).

Seguem dois exemplos em RGB

echo -e "\e[38;2;220;220;50m\e[48;2;50;50;200m Mensagem amarela sobre fundo azul em RGB \e[0m"
echo -e "\e[38;2;255;0;250m\e[48;2;110;0;120m Mensagem rosa sobre fundo roxo em RGB \e[0m"

Além do mundo real