A configuração de um prompt personalizado para o shell Bash, no Linux, é muito fácil de ser feita e pode contribuir para tornar sua sessão de trabalho mais informativa e até mais segura (quando você está logado em vários hosts ao mesmo tempo, um prompt bem configurado mostra imediatamente em que host e em que diretório você está).

Vamos ver como configurar o prompt do Bash em 3 etapas: configuração básica, configuração de cores e configurações extras. Mãos à obra!

Configurações básicas

A variável de ambiente PS1 controla como o prompt do Bash será exibido. Qualquer alteração nessa variável é refletida imediatamente no prompt. Você quer uma seta como prompt?

$ export PS1="--> "
-->

Você pode até escrever um texto em seu prompt:

$ export PS1="Meu Prompt: "
Meu Prompt:

Repare, nos exemplos acima, que basta exportar uma nova versão da variável de ambiente PS1 para que o prompt seja alterado imediatamente, e que essa nova versão da variável deve estar entre aspas. Assim, o formato geral para definir um novo prompt no Bash é: export PS1=”<definição do prompt>”.

Agora que já sabemos como configurar o prompt, basta saber o que preencher na definição do prompt para deixá-lo exatamente do jeito que quisermos. Você já sabe que pode escrever texto puro na definição do prompt, como no exemplo acima, mas isso não é muito útil. O verdadeiro poder informativo do prompt é dado pelos modificadores do prompt, que são (retirados diretamente da “man page” do Bash):

\aan ASCII bell character (07)
\dthe date in "Weekday Month Date" format (e.g., "Tue May 26")
\ean ASCII escape character (033)
\hthe hostname up to the first ‘.’
\Hthe hostname
\jthe number of jobs currently managed by the shell
\lthe basename of the shell’s terminal device name
\nnewline
\rcarriage return
\sthe name of the shell, the basename of $0 (the portion following the final slash)
\tthe current time in 24-hour HH:MM:SS format
\Tthe current time in 12-hour HH:MM:SS format
\@the current time in 12-hour am/pm format
\Athe current time in 24-hour HH:MM format
\uthe username of the current user
\vthe version of bash (e.g., 2.00)
\Vthe release of bash, version + patch level (e.g., 2.00.0)
\wthe current working directory, with $HOME abbreviated with a tilde
\Wthe basename of the current working directory, with $HOME abbreviated with a tilde
\!the history number of this command
\#the command number of this command
\$if the effective UID is 0, a #, otherwise a $
\nnnthe character corresponding to the octal number nnn
\\a backslash
\[´begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
\]end a sequence of non-printing characters

Para definir o seu prompt personalizado basta agora utilizar um ou mais dos modificadores do prompt da tabela acima com os caracteres textuais que você desejar e pronto. Por exemplo, o prompt abaixo mostra o nome do usuário (\u) e o nome do host (\h) separados por um “@”, e também mostra o diretório atual (\w), tudo isso entre conchetes; também mostra um “$” ou “#” dependendo se o usuário é comum ou é root (\$), e o prompt aparece após pular 1 linha (\n):

$ export PS1="\n[\u@\h \w]\$ "

[fdta@hm9399 ~]$ echo $PS1
\n[\u@\h \w]$

[fdta@hm9399 ~]$ ls
includes  logs  php.ini  public_html  tmp

[fdta@hm9399 ~]$ cd /tmp

[fdta@hm9399 /tmp]$

Esse é basicamente o prompt que eu uso em minha rotina diária. Algumas pessoas não gostam de pular uma linha (\n) no prompt, mas eu acho que fica mais fácil de separar na tela os resultados dos diversos comandos.

Experimente os vários modificadores do prompt listados na tabela acima até chegar a um formato que seja agradável e útil para você.

Depois que esse formato for descoberto, basta saber como tornar o prompt permanente para que você não tenha que definir a variável PS1 manualmente todas as vezes que abrir um terminal de comandos. Isso varia um pouco de acordo com a distribuição Linux que você está usando mas o processo é simples: escreva o comando de definição do prompt no arquivo .bashrc ou .bash_profile no diretório HOME de seu usário.

Colorindo o prompt

Algumas vezes é útil definir cores para o prompt ou alguma de suas partes. A definição de cores é bem simples, mas torna o comando de definição do prompt bem complicado de entender, então vamos com calma.

A primeira coisa que tem que ficar clara é que as cores não são um efeito do bash: as cores são um efeito do terminal (linux ou xterm). Então temos que ter um mecanismo de informar ao terminal, e não ao bash, quais as cores que queremos. Mas como fazemos isso? Inserindo, na definição do prompt do bash, alguns caracteres de escape que não serão interpretados pelo bash mas, sim, pelo próprio terminal. E, dentro desses caracteres de escape, colocaremos nosso código de cores. Confuso? Vamos ver isso com calma a seguir.

Em primeiro lugar vamos aprender quais são os caracteres de escape:

  • Marca o início do escape: \e[
  • Fim do escape: m

Uma seqüência de escape então é definida por: \e[ + algum comando para o terminal + m, por exemplo: \e[0m (essa seqüência deve ser lida da seguinte maneira: iniciamos o escape do bash para o terminal com o \e[, depois temos um código 0, e depois fechamos e escape com o caracter m). Especificamente a seqüência “\e[0m” faz com que as cores de background, foreground e definições de texto normal ou em negrito voltem a ser o padrão do terminal.

Então, para mudar a cor do prompt, basta colocar o código adequado entre o \e[ e o m. E quais códigos são esses? Bem, um terminal Linux nos permite configurar várias coisas e todas elas têm um código específico para ser colocado na seqüência de escape. As alterações que podemos fazer são as seguintes:

  1. Códigos para formatação do texto:
    • 1 = negrito ou brilhante (depende do terminal)
    • 2 = mais claro
    • 4 = sublinhado
    • 5 = piscando
    • 7 = reverte as cores do background e foreground
    • 8 = oculto (útil para senhas)
  2. Códigos para limpar formatação do texto:
    • 0 = limpa todos os atributos (lembra-se do \e[0m ?)
    • 21 = retira o negrito
    • 22 = retira o mais claro
    • 24 = retira o sublinhado
    • 25 = retira o texto piscando
    • 27 = retira a reversão de cores do background e foreground
    • 28 = retira o oculto
  3. Códigos para terminais que aceitam 8 ou 16 cores (as cores marcadas com * são para terminais que aceitam 16 cores):
    1. Cor do foreground (texto):
      • 39 = cor padrão do foreground
      • 30 = preto
      • 31 = vermelho
      • 32 = verde
      • 33 = amarelo
      • 34 = azul
      • 35 = magenta
      • 36 = ciano
      • 97 = branco
      • 37 = cinza claro*
      • 90 = cinza escuro*
      • 91 = vermelho claro*
      • 92 = verde claro*
      • 93 = amarelo claro*
      • 94 = azul claro*
      • 95 = magenta claro*
      • 96 = ciano claro*
    2. Cor do background (background do texto, não do terminal):
      • 49 = cor padrão do background
      • 40 = preto
      • 41 = vermelho
      • 42 = verde
      • 43 = amarelo
      • 44 = azul
      • 45 = magenta
      • 46 = ciano
      • 107 = branco
      • 47 = cinza claro*
      • 100 = cinza escuro*
      • 101 = vermelho claro*
      • 102 = verde claro*
      • 103 = amarelo claro*
      • 104 = azul claro*
      • 105 = magenta claro*
      • 106 = ciano claro*

Existem códigos para terminais que aceitam 88 ou 256 cores mas não são mostrados aqui pois, sinceramente, mais do que 8 ou 16 cores para o texto do seu prompt é um pouco demais, não? Se mesmo assim você quiser conhecer esses códigos, sugiro o seguinte texto: bash:tip_colors_and_formatting.

Agora que você já sabe os códigos, vamos ver como usá-los na prática. Veja os exemplos abaixo.

Meu prompt padrão:

export PS1="\n[\u@\h \w]\$ "

[abrantesasf@host02 ~]$

Agora eu quero que o nome no host apareça em vermelho, para me alertar em qual host estou trabalhando no momento (parece bobeira, mas quando você se conecta em vários hosts ao mesmo tempo através de vários terminais, o nome do host bem destacado pode evitar que você faça uma estupidez):

export PS1="\n[\u@\e[31m\h\e[0m \w]\$ "

[abrantesasf@host02 ~]$

Wow! Agora temos o nome do host em vermelho. Como foi feita essa mágica? Note que imediatamente antes do modificador “\h” (que mostra o nome do host), colocamos a seqüência de escape “\e[31m”, e o código 31 é o código para texto de foreground vermelho (velha na lista acima). Assim tudo o que está depois dessa seqüência de escape ficará em vermelho. Note também que imediatamente após o modificador “\h” nós colocamos a seqüência de escape “\e[0m”, que limpa toda a formatação, para que o restante do prompt não fique em vermelho também.

Só existe um pequeno problema no prompt anterior: se você digitar um comando muito grande, que ocupe mais de uma linha, seu terminal ficará completamente embolado. Isso ocorre pois as seqüências de escape ocupam espaço no prompt mas não são exibidas e assim, quando um comando ocupa mais de uma linha, o terminal se perde se não consegue fazer o “word-wrap” corretamente. Para corrigir isso temos que agregar mais 2 modificadores do prompt, o “\[” e o “\]” ao redor das seqüências de escape, para indicar ao terminal que tais seqüências de escape não são imprimíveis. Isso corrige o problema de comandos com mais de 1 linha no terminal. Assim, a versão correta do nosso prompt com o nome do host em vermelho ficará:

export PS1="\n[\u@\[\e[31m\]\h\[\e[0m\] \w]\$ "

[abrantesasf@host02 ~]$

Confuso? No início sim, mas com calma é fácil interpretar: a “\[” informa que o que vem a seguir são caracteres não imprimíveis, depois o “\e[” abre a seqüência de escape, depois o “31” é o código para foreground em vermelho, depois o “m” fecha a seqüência de escape e depois o “\]” informa que terminou o trecho de caracteres não imprimíveis.

E se eu quiser o nome do host em vermelho e negrito? Aí temos que combinar dois códigos, o 31 para o foreground em vermelho e o 1 para o texto em negrito. Sempre que quisermos combinar dois códigos, usamos o “;” como separador. Veja o exmplo:

export PS1="\n[\u@\[\e[31;1m\]\h\[\e[0m\] \w]\$ "

[abrantesasf@host02 ~]$

Observação: o resultado final dependerá do tipo de terminal que está usando e os resultados podem nem sempre ser o que você está esperando. Por exemplo: dependendo do terminal que você está usando o texto não ficará em negrito, ficará mais brilhante; ou se você definir um texto piscando (código 5) ele pode não piscar dependendo de seu terminal. Faça testes para determinar a melhor configuração de formatação para o seu terminal!

E se eu quiser o nome do host em vermelho, com background amarelo?

export PS1="\n[\u@\[\e[31;43m\]\h\[\e[0m\] \w]\$ "

E se eu quiser o nome do host em vermelho e o diretório em azul?

export PS1="\n[\u@\[\e[31m\]\h\[\e[0m\] \[\e[34m\]\w\[\e[0m\]]\$ "

[abrantesasf@host02 ~/teste]$

Use a sua imaginação agora e define um prompt útil para você!

E qual o meu prompt real, aquele que eu uso mesmo no dia a dia? Eu configuro o meu prompt com um pequeno script no arquivo .bash_profile que ajusta as cores dependendo se o usuário é root ou algum usuário comum. Em ambos o nome do host aparece em branco negrito sobre fundo vermelho, e o diretório aparece em azul negrito sobre fundo amarelo; o nome do usuário é que varia: se for root também aparece em branco negrito sobre fundo vermelho, e se for um usuário normal aparece como branco negrito sobre fundo verde. Assim eu tenho uma pista visual rápida se estou conectado como root ou como usuário normal. Segue meu script:

if [ $USER == "root" ]; then
  export PS1="\n[\[\e[41;97;1m\]\u\[\e[0m\]@\[\e[41;97;1m\]\h\[\e[0m\] \[\e[1;34;103m\]\w\[\e[0m\]]# "
else
  export PS1="\n[\[\e[42;97;1m\]\u\[\e[0m\]@\[\e[41;97;1m\]\h\[\e[0m\] \[\e[1;34;103m\]\w\[\e[0m\]]$ "
fi

Se quiser usar esse script, basta colocar no seu arquivo .bash_profile.

Classificado como:                
× Como posso te ajudar?