Colorize your terminal bash prompt
Do the colors of your terminal confuse you when trying to separate your bash promt from your commands and text output? Or are you simply bored of your terminal? Then spice things up with this bash script. Also, your productivity will benefit a lot from it.

I use bash colors in my prompt for:
  • Better identify my bash, my commands and terminal output
  • Identify each host my color to avoid confusions
  • Warn me with a bright color when logged in as root
  • Give my terminals a personal touch


I did not write this script, although I have slightly modified it, and of course, changed the colors I want my bash prompt to be. I came across it several years ago, but did not manage to find the original author.

Using google I found this wiki, where Wolfman is apparently cited as author. If anyone has a hint, please let me know.

By the way, said wiki explains a lot of details about how bash colors work, check it out.

What does it actually look like

Here is a screenshot from my terminal. I use white for the user and host names, black for delimiters, cyan for the current path and green for the command I'm prompted to enter. Note that the black background and white font are not set in the bash theme, but in the terminal configuration.

The code

Type (replace gedit with your favorite text editor, like nano or mousepad):
$ gedit ~/.bashrc

And paste this at the end of it:
## Fancy PWD display function
## The home directory (HOME) is replaced with a ~
## The last pwdmaxlen characters of the PWD are displayed
## Leading partial directory names are striped off
## /home/me/stuff    -> ~/stuff      if USER=me
## /usr/share/big_dir_name -> ../share/big_dir_name if pwdmaxlen=20
## Source: WOLFMAN'S color bash promt

bash_prompt_command() {
 # How many characters of the $PWD should be kept
 local pwdmaxlen=25

 # Indicate that there has been dir truncation
 local trunc_symbol=".."

 # Store local dir
 local dir=${PWD##*/}

 # Which length to use
 pwdmaxlen=$(( ( pwdmaxlen < ${#dir} ) ? ${#dir} : pwdmaxlen ))

 local pwdoffset=$(( ${#NEW_PWD} - pwdmaxlen ))

 # Generate name
 if [ ${pwdoffset} -gt "0" ]

bash_prompt() {
 case $TERM in
   local TITLEBAR='\[\033]0;\u:${NEW_PWD}\007\]'
   local TITLEBAR=""
 local NONE="\[\033[0m\]" # unsets color to term's fg color
 # regular colors
 local K="\[\033[0;30m\]" # black
 local R="\[\033[0;31m\]" # red
 local G="\[\033[0;32m\]" # green
 local Y="\[\033[0;33m\]" # yellow
 local B="\[\033[0;34m\]" # blue
 local M="\[\033[0;35m\]" # magenta
 local C="\[\033[0;36m\]" # cyan
 local W="\[\033[0;37m\]" # white
 # emphasized (bolded) colors
 local EMK="\[\033[1;30m\]"
 local EMR="\[\033[1;31m\]"
 local EMG="\[\033[1;32m\]"
 local EMY="\[\033[1;33m\]"
 local EMB="\[\033[1;34m\]"
 local EMM="\[\033[1;35m\]"
 local EMC="\[\033[1;36m\]"
 local EMW="\[\033[1;37m\]"
 local EMO="\[\033[38;5;208m\]" # Orange bold
 local EMT="\[\033[38;5;118m\]" # Toxic green
 # background colors
 local BGK="\[\033[40m\]"
 local BGR="\[\033[41m\]"
 local BGG="\[\033[42m\]"
 local BGY="\[\033[43m\]"
 local BGB="\[\033[44m\]"
 local BGM="\[\033[45m\]"
 local BGC="\[\033[46m\]"
 local BGW="\[\033[47m\]"
 local UC=$EMW   # user's color
 [ $UID -eq "0" ] && UC=$R # root's color
 PS1="$TITLEBAR ${EMK}[${UC}\u${EMK}@${UC}\h ${EMC}\${NEW_PWD}${EMK}]${EMC}\\$ ${EMT}"

 # without colors: PS1="[\u@\h \${NEW_PWD}]\\$ "
 # extra backslash in front of \$ to make bash colorize the prompt

 # for terminal line coloring, leaving the rest standard
 none="$(tput sgr0)"
 trap 'echo -ne "${none}"' DEBUG

## Bash provides an environment variable called PROMPT_COMMAND. 
## The contents of this variable are executed as a regular Bash command 
## just before Bash displays a prompt. 
## We want it to call our own command to truncate PWD and store it in NEW_PWD

## Call bash_promnt only once, then unset it (not needed any more)
## It will set $PS1 with colors and relative to $NEW_PWD, 
## which gets updated by $PROMT_COMMAND on behalf of the terminal
unset bash_prompt
## EOF

How to set your own colors

Locate following line:
$PS1="$TITLEBAR ${EMK}[${UC}\u${EMK}@${UC}\h ${EMC}\${NEW_PWD}${EMK}]${EMC}\\$

Your bash looks this environment variable up at prints it a the beginning of each command. It is a string we can personalize with content such as your user name and the like. Inside this string will add special characters that tell your terminal what colors to show.

Any text following this directive will take the specified color. In this case K stands for black, and EM for emphasized.
UC: this is the color I use for my user name and host. I specified it to be white (local UC=$EMW)

This is your users name

This is your hosts name

This is the location you are currently it. All terminals have the local variable PWD defined, but this script creates its own which shows the full path to the current directory. You may replace it with PWD if you prefer.

Feel free to experiment a little :)

How does this work

Every time you change the path inside your terminal, the terminal looks if the environment variable "PROMPT_COMMAND" exists, and if it does it executes the script it is pointing to. In our case that is "bash_prompt_command".

So, when you change directory "bash_prompt_command" gets called, which in turn defines the environment variable "NEW_PWD" and writes your current path to it, truncating it if it is longer than 25 characters.

Now, when your terminal promts you for a command, it first prints "PS1", which contains the string we have defined. In said string we wrote special characters, like "\[\033[0;30m\]", using the aliases for them (in this case "EMK"). "PS1" also contains a reference to "NEW_PWD", which contains the path to show.

More less, that is what it boils down to. This explanation is not very rigurous, but it's intent is to give you a basic idea of how it works.

Now if you want to get even more juice out of your terminal, you really got to try TMUX. Find out how it will revolutionize the way you use terminals.

No comments :

Post a Comment