Bash Prompts
Download the original text file---------------------- Begin Copyrighted Material ------------------- $Revision: 1.14 $ $Date: 2013/03/26 17:39:05 $ This article is Copyright 1998-2006,2013 by Douglas Barton. All non-commercial uses of this article are granted explicitly; providing that my name, this copyright notice, and all material between and including the lines that say "Begin Copyrighted Material" and "End of Copyrighted Material" are reproduced intact. All commercial uses of this article are explicitly reserved, and must be arranged with the author. I hope that does not sound extreme, but writing documentation is one of the things I do for a living, and after putting as many hours into something as I have this article, I feel that protecting my interests is well within reason. :) Please feel free to send any comments, suggestions, or questions to dougb@dougbarton.us. I made reference to the "termcap" file that comes with the FreeBSD distribution, the xterm source code, and the "ctlseqs.ms," both from XFree86 3.3.2.3. Of course I also used the Bash man pages. The information in this article is useful for Bash versions 2 through 4. Although the general information about xterm and ANSI escape sequences is probably applicable to other shells, I have not tested it, and have no intention of doing so. Those using Bash 1.14.x can accomplish most of the things mentioned here by using the octal equivalents of the various escape sequences (e.g., substituting \033 for \e, \007 for \a, etc.) and deleting the \[ and \] characters that indicate the boundaries of the non-printable portions of the prompt. This was tested briefly, but I give no guarantees that what you want to do with Bash 1.14 will work. (And really, why are you still using that old version anyway?) If you need help with the basics of creating a prompt string, please see the PROMPTING section of the Bash man page. By including escape sequences in your prompt you can affect various aspects of the terminal you are using; be that an xterm, console device, or other terminal emulation. For example, xterm has the following built in escape sequences (from misc.c in the xterm source): 0: /* new icon name and title*/ 1: /* new icon name only */ 2: /* new title only */ The icon name escape sequences work for X window managers like AfterStep and Window Maker. The title bar sequences work in most window managers. Both also work for some Windows based terminal emulators. An example is PuTTY, which can be found at http://www.chiark.greenend.org.uk/~sgtatham/putty/ Here is a simple example of a prompt using those attributes. PS1='\[\e]1;My Desk\a\e]2;${PWD}\a\]\ [\u@ME \w]\n \#\$ ' To make things easier to read, I used a \ at the end of the first line (which is interpreted by the shell as literally escaping the Return at the end of that line) to continue the string onto the next line. You can use all the examples in this article as they are here, or you can join the lines. Make sure to delete the \ if you join them. Here is how to interpret the elements of that line. PS1= set the shell variable PS1 equal to the string between the two ' marks. Since this variable is only used by Bash, there is no need to export it. \[ start a sequence of non-printing characters \e an ASCII escape character (033 octal) ]1; xterm escape sequence for the name of the icon My Desk literal text string \a an ASCII bell character (007 octal) This ends the first xterm sequence. \e]2;${PWD}\a Put the present working directory in the xterm titlebar. I like to use ${PWD} here because \w puts ~ in the title when you use just 'cd' to return to your home. \] ends the non-printing character sequence [\u@ME \w]\n [ literal [ character \u the username of the current user @ME literal characters \w the current working directory ] literal ] character \n newline \#\$ \# the command number of this command \$ if the effective UID is 0, a #, otherwise a $ Here are some examples of what the prompt looks like using the above string. While I am in my home directory: [myusername@ME ~] 22$ Another directory: [myusername@ME /usr/ports/shells/bash] 23$ Now assume you would like to add color to your prompt. The following will make your prompt a lovely shade of blue, with the caveat that not all ANSI sequences display exactly the same on all terminals. PS1='\[\e]1;My Desk\a\e]2;${PWD}\a\ \e[0;34m\]\ [\u@ME \w]\n \#\$ \ \[\e[m\]' The astute reader will notice that there are two changes to the previous string. Before the first \] which indicates the end of the non-printing sequence, the ANSI escape code for the color blue was added. \e[ ANSI escape sequence indicator 0; use the default attribute (i.e., no bold, underline, etc.) 34 use blue for the foreground color m end of ANSI escape indicator At the end of the prompt we have included another set of non-printable characters with the ANSI escape sequence for "cancel all attributes." This will prevent the text you type in at the prompt from being colored, or otherwise affected. Two very popular uses of color are to indicate that the user has become root, and to use different colors for prompts on different hosts. Because I log into machines on a lot of different hosts, I have developed the following prompt system which allows me to simply change the two variables below for each host. PROMPT_HOSTNAME='ME' PROMPT_COLOR='0;34m' # If I am root, set the prompt to bright red if [ ${UID} -eq 0 ]; then PROMPT_COLOR='1;31m' fi PS1='\[\e]1;${PROMPT_HOSTNAME}\a\e]2;${PROMPT_HOSTNAME}:${PWD}\a\ \e[${PROMPT_COLOR}\]\ [\u@${PROMPT_HOSTNAME} \w]\n \#\$ \ \[\e[m\]' There are other ANSI attributes that can be added, such as bold, inverse (or reverse) video, blink and underline. Not all attributes are supported on all terminals however. For example, the blink attribute is not available in xterm. Underline is generally not available in cons25. A little experimentation with your terminal type will show you what you need to do to achieve the effect you want. A chart with the most common escape sequences of interest; and which ones are supported on xterm, cons25 and vt100 terminals is appended to the end of this article. If your system uses terminfo instead of termcap, your escape codes may be different. Let us say that you would like the hostname part of the prompt to be in reverse video so that it stands out more than the rest. PS1='\[\e[0;34m\]\ [\u@\e[7mME\e[27m \w]\n \#\$ \ \[\e[m\]' The \e[7m sequence is the code for reverse video. On an xterm you can use the sequence \e[27m to cancel the reverse attribute. On other terminals you would either have to use \e[m to cancel all attributes (which works fine if you are not using color) or use the same color sequence you used previously to restore only the color attribute. If you have the same .bash_profile/.bashrc on a machine that you log into from different terminal types, you may find the following to be of use. This allows you to customize your prompt according to what attributes are supported based on the various types of terminals you use. This is based on my experience, you will probably need to modify it to serve your needs. PROMPT_HOSTNAME='ME' PROMPT_COLOR='0;34m' # If I am root, set the prompt to bright red if [ ${UID} -eq 0 ]; then PROMPT_COLOR='1;31m' fi case ${TERM} in xterm*) PS1='\[\e]1;${PROMPT_HOSTNAME}\a\e]2;${PROMPT_HOSTNAME}:${PWD}\a\ \e[${PROMPT_COLOR}\][\u@${PROMPT_HOSTNAME} \w]\n \#\$ \[\e[m\]' ;; vt100) PS1='[\u@${PROMPT_HOSTNAME} \w]\n \#\$ ' ;; *) PS1='\[\e[${PROMPT_COLOR}\][\u@${PROMPT_HOSTNAME} \w]\n \#\$ \[\e[m\]' ;; esac Below is a chart of various interesting attributes for prompting purposes. The first column is a description of the attribute. The second column is the termcap code for that attribute. For more information check 'man 5 termcap'. If the escape code listed does not work for your terminal, check the termcap file for your machine. Those using the terminfo system should check that file and the documentation for it to find the information they need. The last three columns contain the codes for the various terminals, if they are supported. Below this chart is a very long and rather obnoxious prompt string that gives examples of these attributes, and should allow you to test your terminal to see what it can support. It also has the various color codes so you can use it as a reference as well. The bold attribute when combined with a color has the effect of "brightening" the color displayed. On some terminals this makes it an entirely different color. When creating an escape sequence, you can combine the various elements. For example, if you want a string that is bold, underlined, with a red foreground and a green background you would use: \e[1;4;31;42m To read this chart, keep in mind that an ANSI escape sequence starts with \e[ and ends with a literal m. Thus from the chart, the code to turn on the bold attribute is \e[1m. The \e[m sequence turns off all ANSI attributes, and is the only way to cancel things like bold and underline on most terminals. Obviously, "NO" means that terminal does not support that attribute. The ^G for bell is the traditional "hold down the Control key and press G" combination. It can of course be represented in a Bash prompt string with \a. On most terminals, "inverse" and "standout" are identical. Most terminals display unsupported attributes as bold. Attribute termcap xterm cons25 vt100 --------------------------------------------- bold on md 1 1 1 bold off 22 [m inverse on mr 7 7 7 inverse off 27 [m standout on so 7 7 7 standout off se 27 [m [m underline on us 4 NO 4 underline off ue 24 [m blink on mb NO 5 5 blink off 25 [m [m blank/invis mk 8 bell bl ^G ^G ^G all attr off me [m [m [m Here is a sample prompt with the list of color codes included. Where more than one color is indicated it means that color is known to display differently on different terminal types. Other colors may be similarly affected. PS1='[\u@TEST \w]\n \#\$ \n\ \[\ \e[1mBold Text\e[m\n\ \e[4mUnderline Text\e[m\n\ \e[5mBlink Text\e[m\n\ \e[7mInverse Text\e[m\]\n\ Should be normal text Foreground colors: \[\ \e[0;30m30: Black\n\ \e[0;31m31: Red\n\ \e[0;32m32: Green\n\ \e[0;33m33: Yellow\Orange\n\ \e[0;34m34: Blue\n\ \e[0;35m35: Magenta\n\ \e[0;36m36: Cyan\n\ \e[0;37m37: Light Gray\Black\n\ \e[0;39m39: Default\n\ Bright foreground colors: \e[1;30m30: Dark Gray\n\ \e[1;31m31: Red\n\ \e[1;32m32: Green\n\ \e[1;33m33: Yellow\n\ \e[1;34m34: Blue\n\ \e[1;35m35: Magenta\n\ \e[1;36m36: Cyan\n\ \e[1;37m37: White\n\ \e[0;39m39: Default\n\ \e[m\]Background colors: \[\e[1;37m\e[40m40: Black\e[0;49m\n\ \e[41m41: Red\e[0;49m\n\ \e[42m42: Green\e[0;49m\n\ \e[43m43: Yellow\Orange\e[0;49m\n\ \e[44m44: Blue\e[0;49m\n\ \e[45m45: Magenta\e[0;49m\n\ \e[46m46: Cyan\e[0;49m\n\ \e[47m47: Light Gray\Black\e[0;49m\n\ \e[49m49: Default\e[m\]\n' While I know that nothing in this article is going to cure cancer, I hope that it does bring some small joy to your life, and that you have as much fun using this information as I did bringing it all together. -------------------- End of Copyrighted Material ----------------------- The Linux Bash prompt HOWTO maintained by Giles Orr can be found at: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/ There are a lot of interesting ideas in that extensive document, but he makes use of a lot of external programs in his prompts (even when he doesn't have to), which is something I think is a little excessive. But each to his own. :)