quinta-feira, 7 de fevereiro de 2008

Colorizando o modo texto do Ubuntu

Tendo enxugado os enfeites do Ubuntu, agora eu precisava deixar a interface de texto mais agradável para um uso mais constante. Depois de pesquisar um pouco, encontrei as dicas que precisava. Segue um passo a passo:

1. Colorizando o menu do Grub:
Eu praticamente não uso o grub, pois só tenho um sistema operacional instalado e até hoje (desde que fiz esta instalação) não precisei entrar no modo de segurança. Mesmo assim, resolvi modificar as cores dele, como exercício para o que estava por vir.
No terminal, digite:
# sudo nano /boot/grub/menu.lst
No arquivo que irá abrir, procure as seguintes linhas (linhas 25 e 26 aqui):
# Pretty colours
# color red/black black/red
Remova o comment (#) da linha "color..." e modifique ela segundo o seu gosto. No meu grub deixei o menu com as letras vermelhas, fundo preto e seleção vermelha com letras pretas.
Funciona assim: [cor da letra não selecionada]/[cor do fundo não selecionado] [cor da letra selecionada]/[cor do fundo selecionado]
Logo, ficou dessa maneira:
# Pretty colours
color red/black black/red
Para mais opções, veja o GNU GRUB Manual.

2. Agora sim, a diversão vai começar. Sem o usplash, nós podemos visualizar o processo e boot, que são mensagens que dizem como está indo a inicialização do sistema. Muitas distros do Linux vem com essas mensagens configuradas com cores agradáveis e alegres, e bem formatadas, mas este não é o caso do Ubuntu, que cospe uma série de linhas brancas e sem graça na tela quando o usplash é removido. Não tem problema, com algumas edições simples no arquivo que configura estas mensagens do boot, tudo se resolve.
Foi assim que eu fiz:
Primeiro tive que fazer uma busca no Google, na qual encontrei o post Elegant Textual Boot... no fórum inglês do Ubuntu. Lá, além de alguns complementos que usei para a dica anterior, havia um arquivo disponível para substituir o lsb-base-logging.sh que controla a maneira como são exibidas as mensagens durante o boot, entre outras coisas.
Como eu já falei anteriormente, não gosto de "substituir" arquivos do sistema, prefiro criar um backup do arquivo original, dar uma olhada no arquivo novo, e editar o arquivo original manualmente. Então usei este comando:
# sudo nano /etc/lsb-base-logging.sh
Vocês vão notar, assim como eu notei, que o arquivo pode ser dividido em várias partes que começam com "log", por exemplo: log_use... , log_to... , etc. Fui comparando cada um dos meus logs com os logs do arquivo disponível no fórum do Ubuntu e vendo as diferenças, procurando editar apenas aquelas relativas às cores. A primeira coisa que tive que fazer foi inserir os comandos que irão fazer com que as cores sejam mostradas.
O primeiro, log_use_usplash, não estava presente no arquivo que baixei do fórum. Imagino que seja um comando desnecessário, uma vez que não uso usplash. Mas ainda não experimentei removê-lo para ver o que acontece. Como eu já disse, essas mudanças precisam ser feitas com calma.
O segundo, log_to_console, não precisou de não nenhuma mudança.
O terceiro, log_success_msg, foi o primeiro que precisei editar. Eis o original:
log_success_msg () {
if log_use_usplash; then
usplash_write "STATUS $*" || true
fi
log_to_console log_success_msg "$@"
echo " * $@"
}

E aqui, como ele ficou depois de editado:
log_success_msg () {
if log_use_usplash; then
usplash_write "STATUS $*" || true
fi
if log_use_fancy_output; then
GREEN=`$TPUT setaf 2`
NORMAL=`$TPUT setaf 1`
echo " $GREEN* $@$NORMAL"
else
echo " * $@"
fi
}

Notem que a linha log_to_console log_success_msg "$@" foi removida, e substituída por linhas que obviamente lidam com as cores que serão exibidas.
O que realmente controla a cor daquelas mensagens? Seria a palavra "GREEN", como acontece no Grub? Não... Eu testei mudar as palavras, mas não eram elas as responsáveis pelas cores. Mais uma pesquisada no Google e descobri que o que contrala as cores neste contexto é o comando "setaf", como em TPUT setaf 1, TPUT setaf 2, etc...
Estas são as cores disponíveis: red=`tput setaf 1`, green=`tput setaf 2`, yellow=`tput setaf 3`, blue=`tput setaf 4`, purlple=`tput setaf 5`, cyan=`tput setaf 6`
Como o "log" que eu estava editando era, acredito eu, responsável pela mensagem [ok] durante o boot, resolvi deixar, onde está indicada a cor verde, como verde. Mudei apenas o valor do NORMAL. No arquivo do fórum, o NORMAL encontrava-se como NORMAL=`$TPUT op`. mudei para NORMAL=`$TPUT setaf 1`, fazendo com que ele ficasse vermelho. Caso eu não fizesse isso, acredito que a mensagem iria aparecer na cor branca ou na cor escolhida, mais adiante, como valor NORMAL.
O próximo "log" que editei foi o log_failure_msg. Aqui, nenhuma novidade, vejam como ficou:
log_failure_msg () {
if log_use_usplash; then
usplash_write "STATUS $*" || true
fi
if log_use_fancy_output; then
RED=`$TPUT setaf 1`
NORMAL=`$TPUT setaf 1`
echo " $RED*$NORMAL $@"
else
echo " * $@"
fi
}

Mais uma vez, usei o setaf 1 como valor pro NORMAL. O valor atribuído ao RED será para a mensagem [failed] no boot. Felizmente, até o momento, não vi nenhuma destas nesta instalação. (:
Depois veio o log_warning_msg:
log_warning_msg () {
if log_use_usplash; then
usplash_write "STATUS $*" || true
fi
if log_use_fancy_output; then
YELLOW=`$TPUT setaf 3`
NORMAL=`$TPUT setaf 1`
echo " $YELLOW*$NORMAL $@"
else
echo " * $@"
fi
}

Aqui, o valor YELLOW será atribuído a mensagem [warning] no boot. Nenhuma dessas aqui também. (:
Depois temos o log_being_msg, que não precisa de edições, e passamos direto para o log_daemon_msg. Eis aqui sua versão original:
log_daemon_msg () {
if [ -z "$1" ]; then
return 1
fi
if log_use_usplash; then
usplash_write "TEXT $*" || true
fi
log_to_console log_daemon_msg "$@"
if log_use_fancy_output && $TPUT xenl >/dev/null 2>&1; then
COLS=`$TPUT cols`
if [ "$COLS" ] && [ "$COLS" -gt 6 ]; then
COL=`$EXPR $COLS - 7`
else
COLS=80
COL=73
fi

E a versão editada:
log_daemon_msg () {
if [ -z "$1" ]; then
return 1
fi
if log_use_usplash; then
usplash_write "TEXT $*" || true
fi
if log_use_fancy_output && $TPUT xenl >/dev/null 2>&1; then
COLS=`$TPUT cols`
RED=`$TPUT setaf 1`
NORMAL=`$TPUT setaf 1`
if [ "$COLS" ]; then
COL=`$EXPR $COLS - 7`
else
COLS=80
COL=73
fi

A parte que interessa está nos TPUTs. Mais uma vez, ao invés de usar TPUT op para o valor NORMAL, usei TPUT setaf 1, garantido o vermelho para as letras das mensagens dos daemons. Afinal, ficaria ridículo um daemon falando em ciano, como o autor do post no fórum havia sugerido em seu arquivo. Outra coisa interessante aqui é a opção "cols", que está relacionada ao valor das colunas de texto. Infelizmente não era o meu objetivo do dia modificar estes valores, então não poderei falar mais detalhes sobre eles por total falta de conhecimento.
Ao final do log_daemons, temos um enorme de um parágrafo de texto, seguido por um espaço e a seguinte linha:
printf " * $* "
A qual alterei para
printf " $RED* $* $NORMAL"
O próximo "log" é o log_progress_msg, que dispensa alterações, quando então vamos para o log_end_msg.
Eis o original:
log_end_msg () {
if [ -z "$1" ]; then
return 1
fi
if log_use_usplash; then
if [ "$1" -eq 0 ]; then
usplash_write "SUCCESS OK" || true
else
usplash_write "FAILURE failed" || true
fi
fi
log_to_console log_end_msg "$@"
if [ "$COL" ] && [ -x "$TPUT" ]; then
printf "\r"
$TPUT hpa $COL
if [ "$1" -eq 0 ]; then
echo "[ OK ]"
else
printf '['
$TPUT setaf 1 # red
printf fail
$TPUT op # normal
echo ']'
fi
else
if [ "$1" -eq 0 ]; then
echo " ...done."
else
echo " ...fail!"
fi
fi
return $1
}

E aqui o editado:
log_end_msg () {
if [ -z "$1" ]; then
return 1
fi
if log_use_usplash; then
if [ "$1" -eq 0 ]; then
usplash_write "SUCCESS OK" || true
else
usplash_write "FAILURE failed" || true
fi
fi
if [ "$COL" ] && [ -x "$TPUT" ]; then
printf "\r"
$TPUT hpa $COL
GREEN=`$TPUT setaf 2`
NORMAL=`$TPUT setaf 1`
if [ "$1" -eq 0 ]; then
echo "$GREEN[ ok ]$NORMAL"
else
printf '['
$TPUT setaf 1 # red
printf fail
$TPUT op # normal
echo ']'
fi
else
if [ "$1" -eq 0 ]; then
echo " ...done."
else
echo " ...fail!"
fi
fi
return $1
}

Mais uma vez, foram necessárias apenas algumas modificações, e lá estavam as cores. Nos demais "logs" eu não alterei nada. Agora é só salvar e partir para o próximo passo.

Nota: Notei que é possível manter a linha log_to_console log_success_msg "$@" no código.
log_success_msg () {
if log_use_usplash; then
usplash_write "STATUS $*" || true
fi

log_to_console log_success_msg "$@"

if log_use_fancy_output; then
GREEN=`$TPUT setaf 2`
NORMAL=`$TPUT setaf 1`
echo " $GREEN* $@$NORMAL"
else
echo " * $@"
fi
}

O mesmo vale para as linhas warning e failure. Ainda não sei ao certo que diferença isso faz... Tive a impressão que dá mais verbose, mas pode ser que eu esteja errado.

3. Alterando as cores do BASH (prompt de comando). Quem é da época do MS-DOS, assim como eu, deve lembrar que era possível mudar as informações e as cores do prompt de comando editando o arquivo autoexec.bat ou command.com, já nem lembro mais. No Linux não é muito diferente. Basta editar o arquivo .bashrc que o seu prompt ficará colorido. Mais uma vez, usei as dicas do post aquele no fórum, e de umas páginas ali indicadas.
O comando para editar o .bashrc:
# sudo nano ~/.bashrc
Daí procurei pelo seguinte:
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color)
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m
\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
;;
*)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
;;
esac

E comentei todas as linhas com #.
Logo abaixo encontrei o seguinte:
# Comment in the above and uncomment this below for a color prompt
#PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\
]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

Tendo comentado as linhas anteriores, descomentei a linha acima, e a deixei da seguinte forma, seguindo as dicas de uma página da IBM:
# Comment in the above and uncomment this below for a color prompt
PS1='${debian_chroot:+($debian_chroot)}\[\033[00;31m\
]\u@\h\[\033[31m\]:\[\033[00;31m\]\w\[\033[31m\]\$ '

Notem que eu alterei os valores dos números 32, 34 e 00 para 31, caso contrário o prompt iria ficar mais colorido que roupa de palhaço. Deixando todos com o valor 31, faço com que o prompt fique vermelho. As cores possíveis são: preto 30, vermelho 31, verde 32, amarelo 33, azul 34, violeta 35, ciano 36 e branco 37.
Ao salvar e fechar o arquivo, voltando pro prompt, pode ser que você não veja diferença nenhuma. Se você estiver no modo gráfico, editando pelo terminal do gnome, basta fechar e abrir o terminal para ver as mudanças. Tais alterações irão afetar também, o modo texto.
Ainda na página da IBM, existe uma ótima dica de como testar um prompt antes de modificar o arquivo .bashrc, para isso você usa o comando export, como no exemplo abaixo:
# export PS1='${debian_chroot:+($debian_chroot)}\[\033[00;31m\
]\u@\h\[\033[31m\]:\[\033[00;31m\]\w\[\033[31m\]\$ '

Note os números que antecedem o sinal de ";", os "00". Se você modificá-los para 01, eles deixarão as letras em negrito, com a cor mais fraca. Se você modificá-los, por exemplo, para 40, eles deixaram o fundo da tela cinza, ou ciano, caso você use 46...
Basicamente é isso... Fácil não? Basta um pouco de paciência e imaginação ao ler os arquivos de configuração, e você poderá editar o seu Linux da maneira que bem entender. Ter fluência na linguagem Klingon também ajuda.

Nenhum comentário: