Come colorare il prompt di bash

Avere il prompt di bash a colori, oltre che bello, e` comodo. Quando per esempio abbiamo lanciato comandi con un output molto lungo, la possibilita` di separare visivamente gli stessi e` davvero comoda. Il fattore estetico non e` comunque da trascurare.

E` possibile inviare al terminale caratteri di controllo, che modificheranno per esempio il colore, renderanno i font bold o italic (se il terminale supporta questi caratteri, un xterm lo fa — e analogamente piu` o meno tutti i terminali disponibili sotto X11 –, le console testuali di GNU/Linux lo fanno, Terminal.app di MacOS pure). Ora noi specificando il prompt (variabile d’ambiente di PS1) inseriremo questi caratteri di controllo, in modo che il terminale li prenda. Attenzione a rimettere il testo ‘normale’ alla fine del prompt, altrimenti anche tutto quello che verra` scritto poi (vostro input oppure output di programmi) manterra` quell’aspetto [ eventualmente creando un po’ di confusione e perdendo leggibilita`].

(continua…)

Possiamo immettere i caratteri di controllo direttamente, ma a mio avviso e` piu` comodo e leggibile definirli in variabili e poi usare queste al loro posto. Quindi definiremo:

DEFAULT=”\[33[0m\]”
BOLD=”\[33[1m\]”
DIM=”\[33[2m\]”
UNDERLINE=”\[33[4m\]”

BLINK=”\[33[5m\]”
REVERSE=”\[33[7m\]”
HIDDEN=”\[33[8m\]”

BOLD_C=”\[33[22m\]”
UNDERLINE_C=”\[33[24m\]”

BLINK_C=”\[33[25m\]”
REVERSE_C=”\[33[27m\]”
COLOR_C=”\[33[29m\]”

BLACK=”\[33[30m\]”
RED=”\[33[31m\]”

GREEN=”\[33[32m\]”
YELLOW=”\[33[33m\]”
BLUE=”\[33[34m\]”
MAGENTA=”\[33[35m\]”
CYAN=”\[33[36m\]”
WHITE=”\[33[37m\]”

BLACK_B=”\[33[40m\]”
RED_B=”\[33[41m\]”
GREEN_B=”\[33[42m\]”
YELLOW_B=”\[33[43m\]”
BLUE_B=”\[33[44m\]”

MAGENTA_B=”\[33[45m\]”
CYAN_B=”\[33[46m\]”
WHITE_B=”\[33[47m\]”

I primi ‘comandi’ fanno esattamente quello che ci si aspetta dal nome. Quelli che finiscono per _C ‘puliscono’ il flag. Ovvero se avessimo inserito BOLD, con BOLD_C rimetteremmo il testo non BOLD. I colori di tipo ‘BLACK’ definiscono il colore di foreground, quelli che terminano per _B definiscono il background.

Inoltre copio dal manuale di BASH:

\a an ASCII bell character (07)
\d the date in “Weekday Month Date” format (e.g., “Tue May
26″)
\D{format}

the format is passed to strftime(3) and the result is
inserted into the prompt string; an empty format results
in a locale-specific time representation. The braces are
required
\e an ASCII escape character (033)
\h the hostname up to the first `.’

\H the hostname
\j the number of jobs currently managed by the shell
\l the basename of the shell’s terminal device name
\n newline
\r carriage return
\s the name of the shell, the basename of $0 (the portion

following the final slash)
\t the current time in 24-hour HH:MM:SS format
\T the current time in 12-hour HH:MM:SS format
\@ the current time in 12-hour am/pm format
A the current time in 24-hour HH:MM format
\u the username of the current user

\v the version of bash (e.g., 2.00)
\V the release of bash, version + patchelvel (e.g., 2.00.0)
\w the current working directory
\W the basename of the current working directory
\! the history number of this command
\# the command number of this command

\$ if the effective UID is 0, a #, otherwise a $
\nnn the 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

Questi sono caratteri speciali che inseriti nel prompt vi danno quanto a destra. Con qualche esempio si dovrebbe chiarire tutto.

Per esempio il mio prompt e`: [17:15] [riko:Dome] riko $>

Per ottenerlo ho fatto: PS1=”[\A] [\u:\h] \W\$> “

(siamo ancora in bianco e nero, e senza formattazione). Questo funzionera` su ogni terminale, basta che lo mettiate da qualche parte nel vostro .bashrc (per le differenze fra .bashrc e .bash_login o .bash_profile c’e` il mio precedente tutorial).

Per renderlo a colori, niente di piu` facile, inseriamo le variabili precedentemente definite (anche queste vanno nel .bashrc, definite *prima* che ridefiniate PS1). E potrete scrivere quanto segue:

PS1=”$MAGENTA[$WHITE\A$MAGENTA] \ $WHITE[$YELLOW$BOLD\u$WHITE:$CYAN\h$WHITE$BOLD_C] \ $GREEN_B$BLACK\W$DEFAULT $RED\$$WHITE$BOLD>$BOLD_C “

Notate che per andare a capo, ho usato il \. Potete anche scrivere tutto sulla stessa linea. Attenzione che se andate a capo, gli spazi fra l’inizio della linea e l’inizio delle parole *contano*.

X=”A\ B”

non e` la stessa cosa di

X=”A\ B”

Il primo vi dara` AB, il secondo A B.

Tornando a noi…

Se ora lanciaste per esempio una shell dentro Emacs con M-x shell o dentro un’altro terminale cosidetto ‘dumb’, tutti i caratteri di controllo di colori etc. non sarebbero interpretati, ed apparirebbero paro paro nel prompt. Il che renderebbe il tutto parecchio illeggibile. Ecco la soluzione:

if [ “$TERM” == “xterm-color” ] || [ “$TERM” == “linux” ] ; then
PS1=”$MAGENTA[$WHITE\A$MAGENTA] \
$WHITE[$YELLOW$BOLD\u$WHITE:$CYAN\h$WHITE$BOLD_C] \
$GREEN_B$BLACK\W$DEFAULT $RED\$$WHITE$BOLD>$BOLD_C “

else
PS1=”[\A] [\u:\h] \W\$> “
fi;

Una versione migliorata di quanto sopra, anche se abbastanza più pesante da leggere può essere questa:

if [ “$COLORTERM” ] || \

[ `echo $TERM | awk “/(xterm)|(rxvt)/ { print 1 }” ` ] || \
[ “$TERM” == “linux” ] ; then
PS1=”$BLUE_B$GREEN[$CYAN\A$GREEN]\
$CYAN[$MAGENTA$BOLD\u$CYAN:$MAGENTA\h$BOLD_C$CYAN]$DEFAULT \
$GREEN_B$BLUE$BOLD<$CYAN_B$BLUE<$BLUE_B$GREEN\W$BLUE$CYAN_B>$GREEN_B>$BOLD_C$DEFAULT “

export DISPLAY=:0
else
PS1=”[\A] [\u:\h] \W\$> “
fi;

In questo caso verra` usato il prompt colorato solo se il terminale dichiara di saperlo gestire. Volendo potreste preparare una terza versione anche per un xterm (per dire) in bianco e nero, che potrebbe gestire bold e italic, ma non i colori. Ad ogni modo sui sistemi che uso in questo momento mi sono accertato che la versione a colori funziona sempre (non ho terminali che non supportino i colori).

Quanto detto e` testato su Debian GNU/Linux e MacOS X, bash 2.0x.

Edited

Al momento il mio prompt è

    PS1="$BOLD$GREEN\
+-[$CYAN\D{%H}$GREEN:$CYAN\D{%M}$GREEN]--------------------------------------------------------\
[$MAGENTA\u$GREEN:$MAGENTA\h$GREEN]-+$DEFAULT
$BOLD$GREEN\_[$YELLOW\W$GREEN]$DEFAULT\
$GREEN \$ $DEFAULT"
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: