What appears below are my personal notes I wish were part of my long-term memory but don't always seem to fit. I strive for accuracy and clarity and appreciate feedback. If applying any of this information anywhere, confirm for youself the correctness of your work as what you see below might very well be, albeit unintentionally, incorrect or misleading. These notes are here as an easy reference for myself.
Information worthy of a more formal presentation will appear elsewhere than this "Scratch" area. - ksb
I like having a color prompt. Helps in finding where a command started or stopped when scrolling back in the terminal. I also like having lots of info in that prompt, like: user, host, current dir, time (with secs), the return code of the last command and an extra hint if I might be root.
Getting all that right has been surprisingly difficult. I've finally figured out why and here's my solution:
|Table of Contents||References|
The default bash prompt is:
PS1='\u@\h\$ ' ksb@fuzz$As you can see, this gives a prompt consisting of: user name, '@' sign, hostname, '$' symbol (or '#' if you're root) and a space.
You can get colors into your prompt by using escape codes. One code to start the color another to stop it, each surrounded by another kind of escape code to prevent those first ones from confusing bash's idea of how big the prompt is (fun, huh?).
This size of the prompt notion is important when hitting up-arrow and try editing the previous command, or using ctrl-r to search back in your history, or using cut-n-paste, etc. Otherwise your terminal can become quite a mess.
For example to make the above prompt green use:
PS1='\[\e[0;32m\]\u@\h\$\[\e[0m\] ' ksb@fuzz$See the references above for a complete explanation of all this, but briefly breaking this value down into each of its 8 parts:
|\[||stop counting towards length of prompt for now|
|\e[0;32m||starting coloring non-bold green|
|\]||start counting towards length of prompt again|
|\u@\h\$||the prompt: 'user@host$'|
|\[||again stop counting towards length of prompt for now|
|\e[0m||reset to no colors|
|\]||again start counting towards length of prompt again|
|a final space (visually this help separate the prompt for your commands)|
My preferred non-color bash prompt is:
PS1='\u@\h[\W] \t ($?)\$ ' ksb@fuzz[~] 15:55:58 (0)$
This starts off with the default prompt but then adds: current dir (basename), time (with secs) and the return code of last command. Note that the use of single quotes to set that var is important since I want the $? evaluated each time the prompt is presented, not just once when PS1 var is set (which is what would happen if double-quotes were used).
Colorizing this revealed 2 bugs in bash version 3, which appear to have been fixed in bash 4:
Following the idea from the link above, I defined several vars in my ~/.bashrc
blk='\e[0;30m' # Black - Regular red='\e[0;31m' # Red grn='\e[0;32m' # Green ylw='\e[0;33m' # Yellow blu='\e[0;34m' # Blue pur='\e[0;35m' # Purple cyn='\e[0;36m' # Cyan wht='\e[0;37m' # White bblk='\e[1;30m' # Black - Bold bred='\e[1;31m' # Red bgrn='\e[1;32m' # Green bylw='\e[1;33m' # Yellow bblu='\e[1;34m' # Blue bpur='\e[1;35m' # Purple bcyn='\e[1;36m' # Cyan bwht='\e[1;37m' # White ublk='\e[4;30m' # Black - Underline ured='\e[4;31m' # Red ugrn='\e[4;32m' # Green uylw='\e[4;33m' # Yellow ublu='\e[4;34m' # Blue upur='\e[4;35m' # Purple ucyn='\e[4;36m' # Cyan uwht='\e[4;37m' # White bkblk='\e[40m' # Black - Background bkred='\e[41m' # Red bdgrn='\e[42m' # Green bkylw='\e[43m' # Yellow bkblu='\e[44m' # Blue bkpur='\e[45m' # Purple bkcyn='\e[46m' # Cyan bkwht='\e[47m' # White rst='\e[0m' # Text Resetand then define my prompt like this:
PS1="\[$ylw\]\u\[$rst\]@\[$ylw\]\h\[$rst\][\[$cyn\]\W\[$rst\]] \[$grn\]\t\[$rst\] (\[$red\]"'$?'"\[$rst\])\\$ "
Something to point out here is that I need to use double-quotes here for all those 'simplifying' vars to be evaluated. Except of course where I don't want it for the '$?' which I don't want evaluated until the prompt is displayed after each command. Fortunately (and I had to double check this) bash concatenates contiguous strings, so I break it out into 3 separate strings. This leaves the prompt with the value:
ksb@fuzz[~] 18:05:04 (0)$ echo $PS1 \[\e[0;33m\]\u\[\e[0m\]@\[\e[0;33m\]\h\[\e[0m\][\[\e[0;36m\]\W\[\e[0m\]] \[\e[0;32m\]\t\[\e[0m\] (\[\e[0;31m\]$?\[\e[0m\])\$Another thing you might notice is that final \\$. This needs those 2 backslashes so the resulting PS1 var will end up with the desired \$. I think that makes the above an example of 4 different kinds of quotes!
Finally, I'd need to write some conditionals around all this to check both the version of bash to avoid \t & parentheses.