Bash is probably the most common command-line shell in the GNU/Linux world. Although a lot of people use alternate shells (such as Zsh), Bash is still shipped with most mainstream distros as the default. Once you have a lot of different remote machines, all running Bash as the shell, it becomes increasingly difficult to pay attention to the prompt, and typing reboot in a machine different from the one you wanted becomes more likely. I deal with that problem by changing Bash prompts…
First of all, the basics: Bash prompts are just environment variables with special characters you can set and export. Bash has four of these variables: PS1 to PS4, but usually only the first two matters (actually, just PS1 – for a reference on the others, check the manpage). The most common PS1 string is:
spectra@home:~$ echo $PS1
\u@\h:\w\$
spectra@home:~$
This has 4 special characters, escaped with a backslash: \u informing us the username; \h informing us the hostname; \w, informing us the working directory; and \$, which gives us the $ in the end of the prompt (more on this later).
So, essentially, one can change that string to anything else…
spectra@home:~$ PS1="my_shell_prompt\$ "
my_shell_prompt$
Pretty easy. You can check a complete reference of the special characters at the section PROMPTING of bash manpage, but the most useful IMHO are the following:
- \d the date
- \t the time (24-hour format)
- \W the basename of the current working directory
- \! the history number of this command
- \# the command number of this command
- \$ shows # if the UID is 0 (is we are root), or $ for all the rest
Also, as part of the prompt string, one can use ANSI Colors enclosed as non-printing characters (that is between \[ and \]). ANSI sequences always begin with an “ESC[” and end with an “m”. (Yes… Really arbitrary… but that’s the way it is…). ESC can be represented as \e… Here is a list of the most common colors in ANSI sequences:
- Black: 0;30
- Red: 0;31
- Green: 0;32
- Brown: 0;33
- Blue: 0;34
- Purple: 0;35
- Cyan: 0;36
- Light Gray: 0;37
Now, notice that there are two numbers separated by a semi-colon… the first is always 0 (zero) in the colors I pointed above, but it actually refers to an ANSI attribute called Select Graphic Rendition… You can use 0 (zero) to normal colors, 1 for bold, 2 to faint, etc. So \e[0;30m refers to BLACK, \e[1;30m refers to DARK GREY. The Wikipedia has a good article on these escape sequences.
Once you’re satisfied with something printed in a color, to go back to the default (to reset), you issue the \e[0m escape sequence.
So, back to my problem… Each different machine gets a different color for the hostname. On “hospital” machine, for instance, my PS1 looks like:
spectra@hospital:~$ PS1="\[\e[1;33m\]\u\[\e[0m\]@\[\e[0;35m\]\h\[\e[0m\]:\[\e[0;32m\]\w\[\e[0m\]\$ "
spectra@hospital:~$
With \e[0;35m (Purple) for the hostname. On “home” machine, it may be \e[0;34m (Blue)... On “server”, it may be \e[0;36m (Cyan), and so on… After a while, you get used to the color and end up linking the color to the machine… so that typing “reboot” on a machine with the wrong color gets harder than before.
To make the changes permanent, put export PS1 in one of the config script of bash (.bashrc, .bash_profile, etc). On some systems, /etc/environment holds lots of environment variables definitions.
I just scratched the surface… That’s just what works for me… The Bash-Prompt-HOWTO has some interesting examples, and I actually have a friend who uses more esoterical stuff, such as fancybash or bashish, but I’ll leave this up to you…