The bash command prompt in most Linux distributions is pretty bland. If you use the Linux command prompt on a regular basis, perhaps you have noticed that in most Linux distributions, it looks something like this:

[user@hostname dir]$

Don’t get me wrong; this can be quite useful, as it displays useful information about who you are (user), what server you are logged on to (hostname) and what top directory you are in (dir). Not bad.

One gripe I have is that the command prompt can easily blend in with the command output, making it difficult to distinguish between them, especially if you scroll back to look at past command outputs. In addition, if you are logged on to several hosts as different users (which can happen) it becomes increasingly difficult to quickly spot where you are.

Fear not, as there is a solution! It is quite easy to modify the look and color of the command prompt text. So instead of the plain, boring look above, it can look something like this:

Example 1:

[101]user@hostname /etc/sysconfig>

  • The number in the square brackets is the history number of this command.
  • Instead of the top directory you are in, you get the full directory path.
  • Color is red, which easily distinguishes it from the non-colored output.


Example 2:

[12:26:57]user@hostname>

  • The number in the square brackets is the current time in HH:MM:SS format.
  • Fancier color combination, with both background and foreground colors different than the default. 

The prompt settings are stored in the PS1 environment variable. To get the default value of P1, run:

# echo $PS1
[\u@\h \W]\$


Each value in the command prompt is represented by a backslash-escaped string. For the above example:

\u : username
\h : hostname (without FQDN)
\W : basename of the current working directory

There are many other strings available. The most useful include:

\a : an ASCII bell character (07)\d : the date in "Weekday Month Date" format (e.g., "Tue May 26")
\e : an ASCII escape character (033)
\H : the hostname
\l : the basename of the shell’s terminal device name
\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
\w : 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 $
\\ : 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

Let’s spice up our command prompt. For convenience, we start with just ‘#’ for the command prompt and assume that the username is jsmith and the hostname is geeko.lab.dell.com.

# export PS1="[\!]\u@\h>"
[72]jsmith@geeko>

# export PS1="[\d \t]\u@\h>"
[Wed Oct 26 13:37:13]jsmith@geeko>


# export PS1="[\u@\H \W \@]\$"
[jsmith@geeko.lab.dell.com etc 01:39 PM]$

Now let’s add some color:

# export PS1="\e[31m[\!]\u@\h>\e[m"
[109]jsmith@geeko>


\e[ - Start color scheme
x;y – Color pair to use (x;y)
\e[m - Stop color scheme

In the previous example, we used just one color (31 - the ‘m’ after the value is required to tell bash that it is a color specification). When providing one number only, it is assumed to be the foreground color. If adding a second number, it’s assumed to be the background color:

# export PS1="\e[31;43m[\!]\u@\h>\e[m"
[110]jsmith@geeko>


So what exactly are the color combinations available, you ask? Run the following bash script to find out:

#!/bin/bash
# Print array of ANSI colors.
# Foreground text color codes:
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
# Background color codes:
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white

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


As you can see, there is a third value you can prepend to the <foreground>;<background> color combination, which varies the intensity of the colors and can underline the text:

# export PS1="\e[4;34;42m[\!]\u@\h>\e[m"
[111]jsmith@geeko>


You will want to use whatever color combination suits your needs and doesn’t burn your eyes! Enjoy!