O prompt é a parte do terminal que você mais olha no dia — e também uma das mais fáceis de personalizar. Este guia ensina a colorir o PS1 do Bash usando sequências de escape ANSI, com foco em RGB de 24 bits (true color) e, mais importante, em como escolher combinações harmonicamente legíveis, em vez de sair pintando cada palavra de uma cor.
O PS1 é a variável que define o texto do prompt primário. O Bash a reavalia antes de cada comando, expandindo códigos como \u (usuário), \h (host), \w (diretório atual) e \$ (# para root, $ para demais).
As cores entram por sequências de escape ANSI: o caractere ESC (escrito \e ou \033 no Bash) seguido de [, de parâmetros numéricos separados por ; e da letra final m (de SGR — Select Graphic Rendition):
\e[<parâmetros>m → liga um estilo
\e[0m → reseta tudo (sempre termine com ele!)
Para testar qualquer sequência fora do prompt, use echo -e:
echo -e "\e[1;31mVermelho em negrito\e[0m e voltamos ao normal"
Os códigos clássicos usam dois dígitos: 30–37 (primeiro plano), 40–47 (fundo), e as versões claras 90–97 / 100–107.
| Cor | Texto | Fundo | Texto claro | Fundo claro |
|---|---|---|---|---|
| Preto | 30 | 40 | 90 | 100 |
| Vermelho | 31 | 41 | 91 | 101 |
| Verde | 32 | 42 | 92 | 102 |
| Amarelo | 33 | 43 | 93 | 103 |
| Azul | 34 | 44 | 94 | 104 |
| Magenta | 35 | 45 | 95 | 105 |
| Ciano | 36 | 46 | 96 | 106 |
| Branco | 37 | 47 | 97 | 107 |
Atributos de formatação (combináveis com ;):
| Código | Efeito |
|---|---|
| 0 | Reset (desliga tudo) |
| 1 | Negrito / cor intensa |
| 2 | Esmaecido (dim) |
| 3 | Itálico |
| 4 | Sublinhado |
| 5 | Piscante |
| 7 | Invertido (troca texto ↔ fundo) |
| 9 | Tachado |
echo -e "\e[4;36mCiano sublinhado\e[0m" # formatação + cor na mesma sequência
echo -e "\e[1;97;44mBranco sobre azul\e[0m" # texto + fundo + negrito
Quando 16 cores não bastam, os terminais modernos aceitam qualquer cor RGB:
\e[38;2;R;G;Bm → cor de primeiro plano (texto)
\e[48;2;R;G;Bm → cor de fundo
38 = primeiro plano, 48 = fundo2 = modo RGB direto (existe também 5 = paleta de 256 cores)R, G, B = valores de 0 a 255echo -e "\e[38;2;255;140;0mLaranja puro (255,140,0)\e[0m"
echo -e "\e[48;2;60;60;90m\e[38;2;220;220;255mTexto claro sobre azul-acinzentado\e[0m"
Dica: existe um meio-termo —
\e[38;5;Nmusa a paleta de 256 cores (N de 0 a 255). É mais compatível que true color, mas bem menos flexível que RGB. Este guia foca em RGB; se um terminal antigo reclamar, o plano B é o38;5.
\[ e \]Todo caractere não imprimível dentro do PS1 — ou seja, todas as sequências de escape — precisa ser delimitado por \[ e \]. Sem isso, o Readline calcula errado o comprimento do prompt e a edição quebra: o cursor "pula" posições, comandos longos sobrescrevem o início da linha e o histórico (Ctrl+r, setas) embaralha o texto.
# ERRADO — sem os delimitadores, o Readline conta os escapes como caracteres visíveis
PS1="\e[38;2;0;150;255m\u@\h\e[0m \w \$ "
# CERTO — cada sequência de escape embrulhada em \[ \]
PS1="\[\e[38;2;0;150;255m\]\u@\h\[\e[0m\] \w \$ "
Atenção: se o seu prompt "anda" sozinho ou embaralha ao navegar no histórico, quase sempre é
\[/\]faltando — ou escapado errado por aspas duplas (\\[vira texto literal). Ao definir cores em variáveis, monte-as já com os delimitadores, como nos exemplos da seção 6.
Um prompt bonito não é o que tem mais cores, é o que usa cores com intenção. O círculo cromático ajuda: pense na matiz (hue) como um ângulo de 0° a 360° (vermelho ≈ 0°, verde ≈ 120°, azul ≈ 240°).
| Esquema | Posição no círculo | Efeito no prompt | Exemplo RGB |
|---|---|---|---|
| Monocromático | Uma matiz, várias luminosidades | Elegante, impossível errar | (0,95,175) → (0,150,255) → (130,200,255) |
| Análogo | Matizes vizinhas (±30–60°) | Transições suaves, gradientes | verde (90,225,140) → ciano (60,205,220) → azul (80,140,255) |
| Complementar | Matizes opostas (180°) | Contraste forte para destaque | azul (80,160,255) × laranja (255,150,50) |
| Triádico | Três matizes equidistantes (120°) | Vibrante, três papéis claros | verde (90,220,130), roxo (190,120,255), laranja (255,170,60) |
Regras práticas de legibilidade (fundo escuro, o caso mais comum):
0,0,255) sobre preto é quase ilegível; clareie para algo como (80,160,255).48;2 só para selos curtos (ex.: indicador de root), nunca para o prompt inteiro.Cole os exemplos no terminal para testar; para tornar permanente, adicione ao final do ~/.bashrc e rode source ~/.bashrc.
Três luminosidades da mesma matiz azul: a hierarquia visual vem do claro/escuro, não de cores diferentes.
# Monocromático azul: mesma matiz (~210°), três luminosidades
az_esc='\[\e[38;2;0;95;175m\]' # usuário: mais escuro, "peso" visual
az_med='\[\e[38;2;0;150;255m\]' # separadores
az_cla='\[\e[38;2;130;200;255m\]' # host e caminho: mais claros, leitura fácil
reset='\[\e[0m\]'
PS1="${az_esc}\u${az_med}@${az_cla}\h${az_med}:${az_cla}\w${reset}\$ "
Azul como base tranquila; laranja só para o branch — a informação que mais muda e mais importa.
# Complementar (~180° de distância): azul dominante, laranja como acento
azul='\[\e[38;2;80;160;255m\]' # base: user@host
cinza='\[\e[38;2;150;150;150m\]' # apoio neutro: caminho
laranja='\[\e[38;2;255;150;50m\]' # acento: branch git
reset='\[\e[0m\]'
# Retorna "(branch)" se estiver num repositório git
git_branch() {
git branch 2>/dev/null | sed -n 's/^\* \(.*\)/(\1)/p'
}
# O \$ antes de (git_branch) é essencial: adia a execução para cada exibição do prompt
PS1="${azul}\u@\h ${cinza}\w ${laranja}\$(git_branch)${reset}\$ "
Nota: o
\$escapado faz ogit_branchrodar a cada prompt (e não uma única vez ao definir o PS1). É o mesmo mecanismo do\$final, que vira#quando você é root.
Quatro matizes vizinhas interpoladas à mão (verde → turquesa → ciano → azul). A transição é suave porque R, G e B variam pouco de um passo para outro.
# Gradiente análogo: matizes vizinhas, sem saltos bruscos
g1='\[\e[38;2;80;220;120m\]' # verde-menta
g2='\[\e[38;2;50;215;175m\]' # turquesa
g3='\[\e[38;2;40;190;225m\]' # ciano
g4='\[\e[38;2;70;130;250m\]' # azul
reset='\[\e[0m\]'
PS1="${g1}\u${g2}@${g3}\h ${g4}\w${reset}\$ "
# Para criar seu próprio gradiente entre duas cores, interpole cada canal:
# valor = início + (fim - início) × passo / total_de_passos
# Ex.: de (80,220,120) a (70,130,250) em 3 passos → R: 80→77→73→70, G: 220→190→160→130...
Verde, roxo e laranja dividem os papéis (usuário, host, caminho); o $ final fica vermelho quando você é root — aviso visual antes de um rm -rf.
# Triádico (matizes a ~120°): verde (usuário), roxo (host), laranja (caminho)
verde='\[\e[38;2;90;220;130m\]'
roxo='\[\e[38;2;190;120;255m\]'
laranja='\[\e[38;2;255;170;60m\]'
vermelho='\[\e[38;2;255;90;90m\]' # fora do esquema de propósito: alerta
reset='\[\e[0m\]'
if [ "$EUID" -eq 0 ]; then
simbolo="${vermelho}#" # root: vermelho de perigo
else
simbolo="${verde}\$"
fi
PS1="${verde}\u${roxo}@\h ${laranja}\w${reset} ${simbolo}${reset} "
Suportam RGB de 24 bits: GNOME Terminal, Konsole, Alacritty, kitty, WezTerm, Windows Terminal, iTerm2 e a maioria dos emuladores mantidos. Via SSH, o true color costuma passar sem problemas se o terminal local suportar.
Teste rápido — verifique a variável e desenhe um gradiente:
echo $COLORTERM # truecolor ou 24bit = suporte confirmado
# Gradiente de teste: se aparecer suave, é true color; se vier em blocos, não é
awk 'BEGIN{ for(i=0;i<=255;i+=4) printf "\033[48;2;%d;60;%dm ", i, 255-i; print "\033[0m" }'
tmux: o multiplexer precisa ser avisado. No
~/.tmux.conf, useset -g default-terminal "tmux-256color"eset -ag terminal-overrides ",*:RGB"(tmux 3.2+). Sem isso, seu lindo gradiente vira 256 cores dentro do tmux. Mais detalhes em tmux: Configuração (.tmux.conf).
Uma curadoria de cores análogas + um hash do hostname = cada servidor com sua cor, sempre harmoniosa por construção (matizes vizinhas, mesma luminosidade). Você reconhece a máquina pela cor do prompt antes de ler o nome.
# Paleta análoga curada: ciano → verde, mesma faixa de luminosidade (~65%)
_paleta=("80;200;255" "70;215;220" "70;225;180" "90;225;140" "150;220;110")
# Hash do hostname escolhe a cor: mesma máquina, mesma cor, sempre
_idx=$(( $(hostname | cksum | cut -d' ' -f1) % ${#_paleta[@]} ))
cor_host="\[\e[38;2;${_paleta[$_idx]}m\]"
reset='\[\e[0m\]'
PS1="${cor_host}\u@\h${reset} \w \$ "
Variações da mesma ideia:
hostname por $PWD no cksum — cada projeto com sua cor./etc/environment ou de uma variável própria.\u, \h, \w, \[ e \]