Fancy BASH Prompt

The BASH prompt tends to be a bit drab and boring. What it needs is a bit of sprucing up and making a bit more fancy.

This can be done by using colours to display extra information. These colours are described using ANSI Escape Codes.

This requires a terminal that supports colours, but almost all modern ones do.

If you want to try it out yourself, open the .bashrc file in your home directory and edit the PS1 variable:

#Custom PS1 string (prompt)
PS1="\[\033[1;30m\][\[\033[1;32m\]\$(date +%H%M)\[\033[1;30m\]]\[\033[1;30m\][\[\033[1;34m\]\u\[\033[1;30m\]@\[\033[0;35m\]\h\[\033[1;30m\]] \[\033[0;37m\]\W \[\033[1;33m\]\$\[\033[0m\] "
export PS1

Save the file and open a new terminal and admire your new prompt.

Fancy BASH Prompt - The Next Generation

The prompt above works great for your own user. It's a bit of pain to create and maintain a fancy prompt like the above for a system with many users. In truth, the prompt above is also really awful for reading and understanding; all thos \[\033 and stuff all over the place.

The next generation of my prompt does a couple of extra things:

  • Differentiate “root” user
  • Used for all users
  • Easier to maintain and customise
#function for a pretty prompt
function makePrompt
{
        local black="\[\033[0;30m\]"
        local grey="\[\033[1;30m\]"
        local blue="\[\033[0;34m\]"
        local lightBlue="\[\033[1;34m\]"
        local green="\[\033[0;32m\]"
        local lightGreen="\[\033[1;32m\]"
        local cyan="\[\033[0;36m\]"
        local lightCyan="\[\033[1;36m\]"
        local red="\[\033[0;31m\]"
        local lightRed="\[\033[1;31m\]"
        local purple="\[\033[0;35m\]"
        local lightPurple="\[\033[1;35m\]"
        local brown="\[\033[0;33m\]"
        local yellow="\[\033[1;33m\]"
        local lightGrey="\[\033[0;37m\]"
        local white="\[\033[1;37m\]"
        local none="\[\033[0m\]"
 
        # Check the script is being run by root
        if [ "$(id -u)" != "0" ]; then
           local SYMBOL="$"
           local UNAME_COLOR=$lightBlue
           local SYMBOL_COLOR=$yellow
        else
           local SYMBOL="#"
           local UNAME_COLOR=$red
           local SYMBOL_COLOR=$red
        fi
 
        #Custom PS1 string (prompt)
        PS1="$grey[$lightGreen$(date +%H%M)$grey][$UNAME_COLOR\u$grey@$purple\h$grey]$lightGrey \W $SYMBOL_COLOR$SYMBOL$none "
 
        export PS1;
}

My custom PS1 string now uses the variables I'd defined for the colours, making things much easier to read, and allowing someone to much more easily modify the code.

I've also placed it in a function and made most of my variables local (so they won't pollute the system once this script exits).

To make this prompt available to all users of BASH on the system we need to edit the default bashrc file, usually in /etc/bashrc. We'll need to be root to do this, so we need to be sure we've tested the script above in a local .bashrc first before messing with system files.

The important thing here is realise that /etc/bashrc can be called by both interactive and non-interactive scripts, so we need to make sure that our fancy prompt is only used for interactive shells.

The default /etc/bashrc on my Mandriva system already has bits to check for interactive session:

if [ "$PS1" ]; then
    case $TERM in
        xterm*)
            makePrompt
            ;;
[...]

Here you can see me calling my makePrompt function. I have no idea how scoping works in BASH without looking it up, so I've placed the function before where I called it. If that didn't make sense to you, don't worry, all you need to remember is that that you must have the “function makePrompt” part first in your file, before the code snippet above this paragraph.

projects/linux/fancy_bash_prompt.txt · Last modified: 2008/05/22 14:59 by martinsgill
Firefox 3 Mandriva Linux National Secular Society Humanism Lib Dems