Como posso alterar as cores do meu xterm usando as sequências de escape Ansi?

25

Gostaria de alterar as cores (plano de fundo, fonte, primeiro plano) do meu xterm na linha de comando. Ouvi dizer que isso pode ser feito usando seqüências de escape ANSI.

Se isso for possível:

  • Como isso é feito?
  • Posso usar nomes de cores ou devo usar seus códigos RGB?
Nathan Fellman
fonte

Respostas:

27

As seqüências de escape ANSI consistem em uma sequência de caracteres começando com o caractere Escape, caractere 27. O próximo caractere é frequentemente (embora nem sempre) um colchete aberto: [

O comando echo pode enviar caracteres de escape se você especificar -ee usar \epara escape.

O padrão ANSI define 8 cores, além de um modo claro, oferecendo um total de 16 possibilidades. A sequência é:

\e[<number>m

Onde <number>está um dos:

Primeiro plano:

  • 30 preto
  • 31 vermelho
  • 32 Verde
  • 33 Amarelo
  • 34 Blue
  • 35 Magenta
  • 36 ciano
  • 37 Branco

Fundo:

  • 40 Preto
  • 41 vermelho
  • 42 Verde
  • 43 Amarelo
  • 44 azul
  • 45 Magenta
  • 46 ciano
  • 47 Branco

  • 0 Redefinir tudo

  • 1 Negrito

Portanto, para deixar seu primeiro plano vermelho e o segundo plano amarelo:

$ echo -e "\e[31m\e[43m"

E para ativar negrito:

$ echo -e "\e[1m"

Obviamente, você pode combiná-los todos juntos:

$ echo -e "\e[31m\e[43m\e[1m"

Existem muitos outros códigos de escape para fazer outras coisas.

Por exemplo - limpe a tela e mova o cursor para o canto superior esquerdo:

$ echo -e "\e[2J\e[1;1H"

O que é útil ao alterar a cor:

$ echo -e "\e[31m\e[43m\e[1m\e[2J\e[1;1H"

O que mudará as cores, limpará a tela e posicionará o cursor no canto superior esquerdo. Bem, quase no canto superior esquerdo. O eco coloca um retorno de carro, então ele desce uma linha. Você pode adicionar -nao eco para evitar isso se você estiver exigente.

Se você estragar tudo e não conseguir ver o que está digitando, poderá redefinir as cores do terminal para normal pressionando:

Ctrl+v [ 0 m Return

No que você espera é o prompt de comando. Ele se apegará a um comando desconhecido, mas você poderá ver o que está fazendo novamente.

Majenko
fonte
posso usar nomes de cores em vez de códigos de cores?
19711 Nathan Fellman
1
Não, mas você pode atribuir os códigos de cores às variáveis. FGRED = 31; echo -e "\ e [$ {FGRED} m"
Majenko 13/04/11
3
Note-se, no entanto, que vários números de código de cores podem ser separados por ";". Portanto, para deixar seu primeiro plano vermelho e o segundo plano amarelo, você também pode usar o menor: echo -ne '\e[31;43m'(em vez do acima echo -e "\e[31m\e[43m").
Andreas Spindler
Como altero a cor do cursor para 34 Azul?
trusktr
28

Observe que o Xterms moderno suporta cores de 32 bits!

Exemplo simples. Para definir um bom fundo roxo escuro (ei, cada um com o seu) do valor # 53186f, faça:

echo -ne "\033]11;#53186f\007"

Observe que isso muda instantaneamente a cor de toda a janela, não apenas do texto subsequente. Isso é especialmente bom para tornar uma janela obviamente diferente depois da ssh'ing para um servidor (por exemplo). Coloque o 'eco' acima em seu .bashrc e seu terminal mudará automaticamente de cor quando você fizer login no servidor (mas não voltará ao pressionar Ctrl + D)

Você pode gastar HOURS na rede procurando isso - a maioria dos documentos fala apenas das 16 cores ANSI originais.

Fontes: http://www.steike.com/code/xterm-colors/ e http://rtfm.etla.org/xterm/ctlseq.html (consulte "Controles do sistema operacional")

Observe: a sequência de escape acima é válida para o XTerms e pode não funcionar em outras implementações de emuladores de terminal com janelas "tipo XTerm" que podem "parecer" um XTerm. Por exemplo, "gnome-terminal" ou "konsole" têm sequências de escape diferentes ou podem não implementar a mudança de cor.

Greg
fonte
1
Isso não está funcionando para mim, ecoa uma linha em branco sem alterações observáveis ​​no terminal.
Richard
1
Isso funcionou para mim, enquanto os outros não - muito útil, THX
vol7ron
1
+1 muda o plano de fundo da janela e permite nomes de cores - como "verde" em vez de "# 00ff00".
Rob I
1
como estão as cores de 53 bits # 53186f. Conto 24 bits ...
jiggunjer
Alguém sabe como fazer o mesmo com o gnome-terminal?
Wjandrea 11/11
3

Sim. Os terminais ANSI suportam códigos de escape ANSI . Cada código Control Sequence Introducer( CSI) no seguinte formato:

ESC[<<<CODE>>>

O caractere Ascii 27(o ESCcaractere) ou 1bem hexadecimal, seguido por um colchete esquerdo e depois uma letra indicando a ação a ser usada.

Observe que uma lista de ;parâmetros separados pode ser fornecida diretamente antes do <<<CODE>>>parâmetro.

Agora, as cores usam um subconjunto de CSIcódigos, os Select Graphic Renditioncódigos. Estes estão na forma:

ESC[<<<SGR>>>m

O SGRcódigo é passado como um parâmetro the CSI. Relevantes para sua pergunta são os SGRcódigos 30-49. Os códigos 30 a 39 definem a cor do primeiro plano. Os códigos 40 a 49 definem a cor de fundo.

30 - Foreground Black
31 - Foreground Red
32 - Foreground Green
33 - Foreground Yellow
34 - Foreground Blue
35 - Foreground Magenta
36 - Foreground Cyan
37 - Foreground White

40 - Background Black
41 - Background Red
42 - Background Green
43 - Background Yellow
44 - Background Blue
45 - Background Magenta
46 - Background Cyan
47 - Background White

Os códigos 38 e 48 são códigos especiais. Estes são os que permitem usar valores RGB. O formato para estes é:

ESC[38;2;<r>;<g>;<b>m (Foreground)
ESC[48;2;<r>;<g>;<b>m (Background)

Nota: usos alternativos incluem \x1b[<3 or 4>8;5;<web safe color index>m. Com esse uso, há uma codificação de cores completamente diferente. Veja o link na parte superior desta resposta para obter mais informações.

Os códigos 39 e 49 definem as cores de primeiro e segundo plano com seus padrões, que são definidos terminal por terminal.

Na prática, as cores 30-37 40-47 são ligeiramente diferentes do que os rótulos dizem que são.

0 - Black
1 - Darker Red
2 - Darker Green
3 - Dark/Yellow or Brown (varies between terminals)
4 - Dark Blue
5 - Dark Magenta
6 - Dark Cyan
7 - Light Grey

Para obter cores claras, use o SGI para negrito 1,. Negrito é um nome enganador. Não torna a fonte em negrito. Na verdade, aumenta o brilho do texto. Com negrito aplicado, as cores se tornam:

0 - Dark Grey
1 - Bright Red
2 - Bright Green
3 - Bright Yellow
4 - Bright Blue
5 - Bright Magenta
6 - Bright Cyan
7 - White

Nota: os últimos dois blocos de números de cores são relevantes tanto para frente quanto para fundo ( <index> + (30 or 40)).

Para remover todos os estilos (de volta ao modo padrão / normal), use SGR0.

CSIcódigos não são todos gráficos. Por exemplo, ESC[2Jlimpará seu terminal. ESC[<y>;<x>Hdefine a posição do cursor (indexado em 1). Veja o artigo da Wikipedia para mais informações.

Nota: para testá-los, use echo -eou printf.

Élektra
fonte
2

NOTA: O "^ [" é o caractere de escape e é inserido com um CTRL-V, CTRL- [e ^ G é um caractere de sino, inserido com CTRL-V, CTRL-G

O bloco a seguir está no meu .bash_profile e garante que meus xterms neste sistema SEMPRE estejam brancos sobre preto, mesmo depois de fazer logon em outro sistema que pode ter mudado minhas cores.

perl -e '$e=chr(27);print "${e}[37m ${e}[40m ${e}[2J ${e}[1;1H";'
export PS1='^[[37m^[]0;${HOST}: ${PWD}^G^[[40m${USER}@${HOST}:${PWD}
--> '
Mike
fonte
0

verifique também um projeto ScriptEchoColor,
que é completamente feito em scripts bash
, possui pacotes para o ubuntu aqui,
mas esses scripts podem ser instalados em qualquer distro, se você souber (o mais recente pode ser baixado do seu git também).

você pode usar nomes de cores reduzidos ou estendidos, como:

echoc "@rRedFg@{/blue}BlueFg@{/GREEN}GreenBg"

uma amostra: insira a descrição da imagem aqui

Além disso, verifique o xtermcontrol , para um controle mais extenso sobre o xterm em si (não apenas os caracteres).

Aquarius Power
fonte
0

Entre os muitos códigos ANSI CSI, há um chamado SGR, ou Select Graphic Rendition. Este é ESC,, [parameters,, monde os parâmetros são um ou mais números inteiros no formato ASCII, separados por ponto e vírgula. Os vários parâmetros SGR diferentes estão listados na página da Wikipedia acima (embora não entrem em detalhes completos para todos eles).

Alguns parâmetros, como 1(intensidade em negrito ou aumento) e 31(texto em vermelho), são independentes e podem ser usados ​​individualmente ou combinados, como em ESC[31mou ESC[1;31mpara fornecer texto padrão em primeiro plano em vermelho e em negrito, respectivamente.

Outros consideram os próprios parâmetros, que são simplesmente fornecidos após o código como mais números separados por ponto e vírgula. Assim, por exemplo, ESC[38;5;219mexibirá o texto em primeiro plano na cor estendida número 219 e ESC[38;2;150;100;50mna cor com o valor RGB 150, 100, 50. Nesse caso, 38é o comando "cor de primeiro plano de conjunto estendido", que é sempre seguido por um subcomando. O subcomando 2usa três parâmetros, os valores dos componentes vermelho, verde e azul. Diferentemente, o subcomando 5assume apenas mais um valor, um número de 0 a 255 especificando uma cor de uma tabela na qual o terminal está configurado.

A seguinte função shell pode ser útil para usar esses códigos:

sgr() {
    local codes=${1:-0}; shift
    for c in "$@"; do codes="$codes;$c"; done
    echo -n -e "\e[${codes}m"
}

Você pode usá-lo assim:

normal=$(sgr 0)
red=$(sgr 31)
echo "Text can be $(sgr 1)made boldface$(sgr 0)" \
     " or ${red}colored red${normal}" \
     " or $(sgr 31 1)even both at the same time$(sgr)."

Observe que, se você não fornecer parâmetros para sgr()o código SGR 0, significa desativar todos os atributos, redefinindo o texto para qualquer que seja o padrão para esse terminal.

Curt J. Sampson
fonte
1
Tecnicamente aqueles ESC[38... me ESC[38... mpode / deve (depende de sua fonte de informação - a um ser supremo, eu acredito, itu.int/rec/T-REC-T.416-199303-I ) deve usar o, caso contrário, reservado, caractere :(para separar os elementos do parâmetro ), para que ;seja usado apenas entre as seqüências de parâmetros completas - ou seja, ESC[38;2;150;100;50mdeve ser gravado ESC[38:2::150:100:50m...
SlySven em 27/2
... infelizmente, as implementações geralmente esquecem o ID do espaço de cores entre o 2e 150- como ninguém, que eu saiba , já definiu qual valor deve ser usado lá, o padrão vazio deve ser usado - mas geralmente é omitido e usar apenas ;como separador impossibilita o processamento confiável das informações de acordo com a especificação.
SlySven 27/01