Wednesday, February 10, 2010

Prompt Tricks

Kind book reader Bruce Fowler sent me a note shortly after the book was released providing some feedback on Chapter 14, "Customizing The Prompt."  He pointed out (quite rightly) that there are many practical things you can do with the shell prompt that can make your command line experience easier and more enjoyable.  One of his favorites was simply coloring the shell prompt so that it is easier to see in a long stream of text output.


Your shell prompt is defined by the contents of a shell variable named PS1.  The variable contains a combination of literal text and special codes that expand into various elements of the prompt when it is displayed.  We can easily modify our prompt to give it the color green.

First, we'll save a copy of our current prompt string in a new variable named PS1_OLD:

me@linuxbox:~$ PS1_OLD="$PS1"

Later, if you want to revert to the original prompt settings, you can do this:

me@linuxbox:~$ PS1="$PS1_OLD"

Next, we'll add ANSI escape sequences to the beginning and end of our prompt string to set the color to green and back to its original color:

me@linuxbox:~$  PS1="\[\033[01;32m\]$PS1\[\033[00m\]"

Now, we have a green prompt!

me@linuxbox:~$

Let's break this prompt string down:

Element Meaning
\[ Beginning of non-printing sequence. You need to tell bash that the sequence that follows does not actually print characters on the screen (it only sends control instructions to your terminal emulator setting the color). bash would otherwise count the characters and this would mess up bash's calculation of the cursor position which it does to support command line editing.
\033[01;32m ANSI sequence to set foreground text green.
\] End of non-printing sequence.
$PS1 Original prompt string. We're embedding the original prompt string in the middle to retain its design.
\[ Beginning of non-printing sequence. Again, the sequence that follows to reset the colors does not print characters on the screen.
\033[00m Sequence to reset attributes and color to previous settings.
\] End of non-printing sequence.

To make this change permanent, add this line to your .bashrc file:

PS1="\[\033[01;32m\]$PS1\[\033[00m\]"

Bruce also suggested making the prompt for the root account (if your system is so equipped) a different color (like red) to remind you that you are operating as the superuser.

Finally, Bruce included a short script that he picked up from a USENET group which displays all the possible color and attributes supported by ANSI:

#!/bin/sh
############################################################
# Nico Golde (nico(at)ngolde.de) Homepage: http://www.ngolde.de
# Last change: Mon Feb 16 16:24:41 CET 2004
############################################################

for attr in 0 1 4 5 7 ; do
    echo "----------------------------------------------------------------"
    printf "ESC[%s;Foreground;Background - \n" $attr
    for fore in 30 31 32 33 34 35 36 37; do
        for back in 40 41 42 43 44 45 46 47; do
            printf '\033[%s;%s;%sm %02s;%02s  ' $attr $fore $back $fore $back
        done
        printf '\n'
    done
    printf '\033[0m'
done

When executed, the results look like this:



Further Reading