Difference between revisions of "Bash/Prompt customization"

From ArchWiki
Jump to: navigation, search
(Return value visualisation)
m (See also: man page link)
 
(232 intermediate revisions by 51 users not shown)
Line 1: Line 1:
 
[[Category:Eye candy]]
 
[[Category:Eye candy]]
 
[[Category:Command shells]]
 
[[Category:Command shells]]
 +
[[de:Bash-Prompt anpassen]]
 
[[es:Color Bash Prompt]]
 
[[es:Color Bash Prompt]]
 
[[it:Color Bash Prompt]]
 
[[it:Color Bash Prompt]]
 +
[[ja:Bash カラープロンプト]]
 
[[ru:Color Bash Prompt]]
 
[[ru:Color Bash Prompt]]
There are a variety of possibilities for [[Bash]]'s prompt (PS1), and customizing it can help you be more productive at the command line. You can add additional information to your prompt, or you can simply add color to it to make the prompt stand out.
+
[[zh-CN:Color Bash Prompt]]
 +
{{Related articles start}}
 +
{{Related|Bash}}
 +
{{Related|Environment variables}}
 +
{{Related|Git#Git prompt}}
 +
{{Related articles end}}
 +
Bash has several prompts which can be customized to increase productivity, aesthetic appeal, and nerd cred.
  
==Basic prompts==
+
== Prompts ==
The following settings are useful for distinguishing the root prompt from non-root users.
+
  
*Edit Bash's personal configuration file:
+
Bash has four prompts that can be customized:
$ nano ~/.bashrc
+
  
*Comment out the default prompt:
+
* {{ic|PS1}} is the primary prompt which is displayed before each command, thus it is the one most people customize.
#PS1='[\u@\h \W]\$ '
+
* {{ic|PS2}} is the secondary prompt displayed when a command needs more input (e.g. a multi-line command).
 +
* {{ic|PS3}} is not very commonly used. It is the prompt displayed for Bash's {{ic|select}} built-in which displays interactive menus. Unlike the other prompts, it does not expand [[#Bash escape sequences|Bash escape sequences]]. Usually you would customize it in the script where the {{ic|select}} is used rather than in your {{ic|.bashrc}}.
 +
* {{ic|PS4}} is also not commonly used. It is displayed when debugging bash scripts to indicate levels of indirection. The first character is repeated to indicate deeper levels.
  
*Add the following green prompt for regular users:
+
All of the prompts are customized by setting the corresponding variable to the desired string (usually in {{ic|~/.bashrc}}), for example
<div style="font-family: monospace; white-space: pre; overflow: auto; margin: 1em 3em; padding: 1em; border: 3px solid #bcd; background-color: black; color: #aaa;"><span style="color: #0f0">[chiri@zetsubou ~]$</span> <span style="text-decoration: blink;">_</span></div>
+
PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
+
  
*Edit root's .bashrc file; copy it from /etc/skel if the file is not present:
+
  export PS2='> '
  # nano /root/.bashrc
+
*Assign a red prompt for root:
+
<div style="font-family: monospace; white-space: pre; overflow: auto; margin: 1em 3em; padding: 1em; border: 3px solid #bcd; background-color: black; color: #aaa;"><span style="color: #f00">[root@zetsubou ~]#</span> <span style="text-decoration: blink;">_</span></div>
+
PS1='\[\e[1;31m\][\u@\h \W]\$\[\e[0m\] '
+
  
===Slightly fancier prompts===
+
== Techniques ==
*A green and blue prompt for regular users:
+
<div style="font-family: monospace; white-space: pre; overflow: auto; margin: 1em 3em; padding: 1em; border: 3px solid #bcd; background-color: black; color: #aaa;"><span style="color: #0a0">chiri</span> <span style="color: #00f">~/docs</span> <span style="color: #0f0">$</span> echo "sample output text"<nowiki>
+
sample output text
+
</nowiki><span style="color: #0a0">chiri</span> <span style="color: #00f">~/docs</span> <span style="color: #0f0">$</span> <span style="text-decoration: blink;">_</span></div>
+
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\e[m\] \[\e[1;37m\]'
+
  
This will give a very pleasing, colorful prompt and theme for the console with bright white text.
+
While one can simply set their prompt to a plain string, there are a variety of techniques for making the prompt more dynamic and useful.
  
The string above contains color-set escape sequences (start coloring: \[\e[color\], end coloring: \[\e[m\]) and information placeholders:
+
=== Bash escape sequences ===
  
* \u - Username. The original prompt also has \h, which prints the host name.
+
When printing the prompt string, Bash looks for certain backslash-escaped characters and will expand them into special strings. For example, {{ic|\u}} is expanded into the current username and {{ic|\A}} is expanded to the current time. So a PS1 of {{ic|'\A \u $ '}} would be printed like {{ic|17:35 ''username'' $ }}.
* \w - Current absolute path. Use \W for current relative path.
+
* \$ - The prompt character (eg. '#' for root, '$' for regular users).  
+
  
The last color-set sequence, "\[\e[1;37m\]", is not closed, so the remaining text (everything typed into the terminal, program output and so on) will be in that (bright white) color. It may be desirable to change this color, or to delete the last escape sequence in order to leave the actual output in unaltered color.  
+
Check the "PROMPTING" section of the Bash man page for a complete list of escape sequences.
  
*A red and blue prompt for root:
+
=== Terminfo escape sequences ===
<div style="font-family: monospace; white-space: pre; overflow: auto; margin: 1em 3em; padding: 1em; border: 3px solid #bcd; background-color: black; color: #aaa;"><span style="color: #a00">root</span> <span style="color: #00f">~/docs</span> <span style="color: #a00">#</span> <span style="color: #0a0">echo "sample output text"<nowiki>
+
sample output text
+
</nowiki></span><span style="color: #a00">root</span> <span style="color: #00f">~/docs</span> <span style="color: #a00">#</span> <span style="color: #0a0"><span style="text-decoration: blink;">_</span></span></div>
+
PS1='\[\e[0;31m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[0;31m\]\$ \[\e[m\]\[\e[0;32m\]'
+
  
This will give you a red designation and green console text.
+
Aside from the escape characters recognized by Bash, most terminals recognize special escape sequences that affect the terminal itself rather than printing characters. For example they might change the color of subsequent printed characters, move the cursor to an arbitrary location, or clear the screen. These escape sequences can be somewhat illegible and can vary from terminal to terminal, so they are documented in the terminfo database. To see what capabilities your terminal supports, run
  
Once you have made your changes to .bashrc, to execute your changes:
+
  $ infocmp
  $ source ~/.bashrc
+
  
==Advanced prompts==
+
The capability names (the part before the =) can be looked up in the terminfo man page for a description of what they do. For example, {{ic|setaf}} sets the foreground color of whatever text is printed after it. To get the escape code for a capability, you can use the {{ic|tput}} command. For example
  
===Load/Mem Status for 256colors===
+
$ tput setaf 2
This is not even pushing the limits. Other than using 'sed' to parse the memory and load average (using the ''-u'' option for non-buffering), and the builtin ''history'' to save your history to your ''HISTFILE'' after every command, which you may find incredibly useful when dealing with crashing shells or subshells, this is essentially just making BASH print variables it already knows, making this extremely fast compared to prompts with non-builtin commands.
+
  
This prompt is from AskApache.com's [http://www.askapache.com/linux-unix/bash-power-prompt.html BASH Power Prompt article], which goes into greater detail.  It is especially helpful for those wanting to understand 256 color terminals, ncurses, termcap, and terminfo.
+
prints the escape sequence to set the foreground color to green.
  
This is for '''256 color terminals''', which is where the '''\033[38;5;22m''' terminal escapes come from.
+
{{Note|If tput commands are failing for you, ensure that you have set the correct {{ic|TERM}} value for your shell. For example, if you have set {{ic|xterm}} instead of {{ic|xterm-256color}}, {{ic|tput setaf}} will only work with color numbers 0-7.}}
{{bc|1=
+
<span style="color:#0b0">802</span><span style="color:#005f00">/1024MB</span>      <span style="color:#5f00af">1.28 1.20 1.13 3/94 18563</span>
+
<span style="color:#555">[5416:17880 0:70]</span> <span style="color:0bb">05:35:50 Wed Apr 21</span> <span style="color:#555">[</span><span style="color:#2b47ff">srot@host.sqpt.net</span><span style="color:#555">:</span><span style="color:#bbb">/dev/pts/0</span> <span style="color:#00bb00">+1</span><span style="color:#555">]</span> <span style="color:#000">~<br />
+
(1:70)$ <span style="text-decoration: blink;">_</span></span>
+
}}
+
  
  PROMPT_COMMAND='history -a;echo -en "\033[m\033[38;5;2m"$(( `sed -nu "s/MemFree:[\t ]\+\([0-9]\+\) kB/\1/p" /proc/meminfo`/1024))"\033[38;5;22m/"$((`sed -nu "s/MemTotal:[\t ]\+\([0-9]\+\) kB/\1/Ip" /proc/meminfo`/1024 ))MB"\t\033[m\033[38;5;55m$(< /proc/loadavg)\033[m"'
+
To practically incorporate these capabilities into your prompt, you can use Bash's command substitution and string interpolation. For example
  PS1='\[\e[m\n\e[1;30m\][$$:$PPID \j:\!\[\e[1;30m\]]\[\e[0;36m\] \T \d \[\e[1;30m\][\[\e[1;34m\]\u@\H\[\e[1;30m\]:\[\e[0;37m\]${SSH_TTY} \[\e[0;32m\]+${SHLVL}\[\e[1;30m\]] \[\e[1;37m\]\w\[\e[0;37m\] \n($SHLVL:\!)\$ '
+
  
===List of colors for prompt and Bash===
+
{{hc|~/.bashrc|<nowiki>GREEN="\[$(tput setaf 2)\]"
Add this to your Bash file(s) to define colors for prompt and commands:
+
RESET="\[$(tput sgr0)\]"
{{bc|<nowiki>txtblk='\e[0;30m' # Black - Regular
+
txtred='\e[0;31m' # Red
+
txtgrn='\e[0;32m' # Green
+
txtylw='\e[0;33m' # Yellow
+
txtblu='\e[0;34m' # Blue
+
txtpur='\e[0;35m' # Purple
+
txtcyn='\e[0;36m' # Cyan
+
txtwht='\e[0;37m' # White
+
bldblk='\e[1;30m' # Black - Bold
+
bldred='\e[1;31m' # Red
+
bldgrn='\e[1;32m' # Green
+
bldylw='\e[1;33m' # Yellow
+
bldblu='\e[1;34m' # Blue
+
bldpur='\e[1;35m' # Purple
+
bldcyn='\e[1;36m' # Cyan
+
bldwht='\e[1;37m' # White
+
unkblk='\e[4;30m' # Black - Underline
+
undred='\e[4;31m' # Red
+
undgrn='\e[4;32m' # Green
+
undylw='\e[4;33m' # Yellow
+
undblu='\e[4;34m' # Blue
+
undpur='\e[4;35m' # Purple
+
undcyn='\e[4;36m' # Cyan
+
undwht='\e[4;37m' # White
+
bakblk='\e[40m'  # Black - Background
+
bakred='\e[41m'  # Red
+
bakgrn='\e[42m'  # Green
+
bakylw='\e[43m'  # Yellow
+
bakblu='\e[44m'  # Blue
+
bakpur='\e[45m'  # Purple
+
bakcyn='\e[46m'  # Cyan
+
bakwht='\e[47m'  # White
+
txtrst='\e[0m'    # Text Reset</nowiki>}}
+
  
<br/>
+
export PS1="${GREEN}my prompt${RESET}> "</nowiki>}}
Or if you prefer color names you will know how to spell without a special decoder ring and want high intensity colors:
+
<div style="font-family: monospace; white-space: pre; padding: 1em; background-color: black; border: 1px solid #bcd; color: white;"><span style="color: #0f0">my prompt</span>> </div>
{{bc|<nowiki># Reset
+
Color_Off='\e[0m'      # Text Reset
+
  
# Regular Colors
+
{{Note|Wrapping the tput output in {{ic|\[ \]}} is recommended by the Bash man page. This helps Bash ignore non-printable characters so that it correctly calculates the size of the prompt.}}
Black='\e[0;30m'        # Black
+
Red='\e[0;31m'          # Red
+
Green='\e[0;32m'        # Green
+
Yellow='\e[0;33m'      # Yellow
+
Blue='\e[0;34m'        # Blue
+
Purple='\e[0;35m'      # Purple
+
Cyan='\e[0;36m'        # Cyan
+
White='\e[0;37m'        # White
+
  
# Bold
+
=== ANSI escape sequences ===
BBlack='\e[1;30m'      # Black
+
BRed='\e[1;31m'        # Red
+
BGreen='\e[1;32m'      # Green
+
BYellow='\e[1;33m'      # Yellow
+
BBlue='\e[1;34m'        # Blue
+
BPurple='\e[1;35m'      # Purple
+
BCyan='\e[1;36m'        # Cyan
+
BWhite='\e[1;37m'      # White
+
  
# Underline
+
Unfortunately, valid ANSI escape sequences may be missing from your terminal's terminfo database. This is especially common with escape sequences for newer features such as 256 color support. In that case you cannot use tput, you must input the escape sequence manually.
UBlack='\e[4;30m'      # Black
+
URed='\e[4;31m'        # Red
+
UGreen='\e[4;32m'      # Green
+
UYellow='\e[4;33m'      # Yellow
+
UBlue='\e[4;34m'        # Blue
+
UPurple='\e[4;35m'      # Purple
+
UCyan='\e[4;36m'        # Cyan
+
UWhite='\e[4;37m'      # White
+
  
# Background
+
See [[Wikipedia:ANSI escape code]] for examples of escape sequences. Every escape sequence starts with a literal escape character, which you can input using the Bash escape sequence {{ic|\e}}. So for example,{{ic|\e[48;5;209m}} sets the background to a peachy color (if you have 256 color support) and {{ic|\e[2;2H}} moves the cursor near the top-left corner of the screen.
On_Black='\e[40m'      # Black
+
On_Red='\e[41m'        # Red
+
On_Green='\e[42m'      # Green
+
On_Yellow='\e[43m'      # Yellow
+
On_Blue='\e[44m'        # Blue
+
On_Purple='\e[45m'      # Purple
+
On_Cyan='\e[46m'        # Cyan
+
On_White='\e[47m'      # White
+
  
# High Intensity
+
In cases where Bash escape sequences are not supported (such as PS3) you can get a literal escape character using Bash's printf builtin:
IBlack='\e[0;90m'      # Black
+
IRed='\e[0;91m'        # Red
+
IGreen='\e[0;92m'      # Green
+
IYellow='\e[0;93m'      # Yellow
+
IBlue='\e[0;94m'        # Blue
+
IPurple='\e[0;95m'      # Purple
+
ICyan='\e[0;96m'        # Cyan
+
IWhite='\e[0;97m'      # White
+
  
# Bold High Intensity
+
ESC=$(printf "\e")
BIBlack='\e[1;90m'      # Black
+
PEACH="$ESC[48;5;209m"
BIRed='\e[1;91m'        # Red
+
BIGreen='\e[1;92m'      # Green
+
BIYellow='\e[1;93m'    # Yellow
+
BIBlue='\e[1;94m'      # Blue
+
BIPurple='\e[1;95m'    # Purple
+
BICyan='\e[1;96m'      # Cyan
+
BIWhite='\e[1;97m'      # White
+
  
# High Intensity backgrounds
+
=== Embedding commands ===
On_IBlack='\e[0;100m'  # Black
+
On_IRed='\e[0;101m'    # Red
+
On_IGreen='\e[0;102m'  # Green
+
On_IYellow='\e[0;103m'  # Yellow
+
On_IBlue='\e[0;104m'    # Blue
+
On_IPurple='\e[10;95m'  # Purple
+
On_ICyan='\e[0;106m'    # Cyan
+
On_IWhite='\e[0;107m'  # White
+
</nowiki>}}
+
  
To use in commands from your shell environment:
+
If you want to add the output of some command to your prompt, you might be tempted to use command substitution. For example, to add the amount of free memory to your prompt you might try:
$ echo -e "${txtblu}test"
+
{{hc|1=export PS1="$(awk '/MemFree/{print $2}' /proc/meminfo) prompt > "|2=53718 prompt >
<font color='blue'>test</font>
+
53718 prompt >
$ echo -e "${bldblu}test"
+
53718 prompt >}}
<font color='lightblue'><b>test</b></font>
+
$ echo -e "${undblu}test"
+
<font color='lightblue'><b><u>test</u></b></font>
+
$ echo -e "${bakblu}test"
+
<span style="color: white; background-color: lightblue"><b>test</b></span>
+
  
To use in a prompt (note double quotes to enable $color variable expansion and <nowiki>\[ \]</nowiki> escapes around them so they are not counted as character positions and the cursor position is not wrong):
+
But this doesn't work; the amount of memory shown is the same every time! This is because the command is run once, when PS1 is first set, and never again. The trick is to simply prevent the substitution either by escaping the {{ic|$}} or by defining it in single quotes&mdash;either way it will be substituted when the prompt is actually displayed:
PS1="\[$txtblu\]foo\[$txtred\] bar\[$txtrst\] baz : "
+
  
If you experience premature line wrapping when entering commands at the prompt then missing escapes is most likely to be the reason.
+
export PS1="\$(awk '/MemFree/{print \$2}' /proc/meminfo) prompt > "
 +
# or
 +
export PS1='$(awk "/MemFree/{print \$2}" /proc/meminfo) prompt > '
  
===Prompt escapes===
+
To prevent long commands from making your PS1 huge, you can define functions:
The various Bash prompt escapes listed in the manpage:
+
Bash allows these prompt strings to be customized by inserting a
+
number of ''backslash-escaped special characters'' that are
+
decoded as follows:
+
+
  \a        an ASCII bell character (07)
+
  \d        the date in "Weekday Month Date" format (e.g., "Tue May 26")
+
  \D{format} the format is passed to strftime(3) and the result
+
              is inserted into the prompt string an empty format
+
              results in a locale-specific time representation.
+
              The braces are required
+
  \e        an ASCII escape character (033)
+
  \h        the hostname up to the first `.'
+
  \H        the hostname
+
  \j        the number of jobs currently managed by the shell
+
  \l        the basename of the shell's terminal device name
+
  \n        newline
+
  \r        carriage return
+
  \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
+
  \u        the username of the current user
+
  \v        the version of bash (e.g., 2.00)
+
  \V        the release of bash, version + patch level (e.g., 2.00.0)
+
  \w        the current working directory, with $HOME abbreviated with a tilde
+
  \W        the basename of 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 $
+
  \nnn      the character corresponding to the octal number nnn
+
  \\        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
+
         
+
  The command number and the history number are usually different:
+
  the history number of a command is its position in the history
+
  list, which may include commands restored from the history file
+
  (see HISTORY below), while the command number is the position in
+
  the sequence of commands executed during the current shell session.
+
  After the string is decoded, it is expanded via parameter
+
  expansion, command substitution, arithmetic expansion, and quote
+
  removal, subject to the value of the promptvars shell option (see
+
  the description of the shopt command under SHELL BUILTIN COMMANDS
+
  below).
+
  
===Positioning the cursor===
+
{{bc|1=free_mem()
The following sequence sets the cursor position:
+
{
\[\033[<row>;<column>f\]
+
    awk '/MemFree/{print $2}' /proc/meminfo
 +
}
  
The current cursor position can be saved using:
+
export PS1='$(free_mem) prompt > '}}
\[\033[s\]
+
  
To restore a position, use the following sequence:
+
{{Note|You can use terminfo/ANSI escape sequences inside substituted functions but '''not''' Bash escapes. In particular {{ic|\[ \]}} won't work for surrounding non-printable characters. Instead you can use the octal escapes {{ic|\001}} and {{ic|\002}} (e.g. using {{ic|printf}} or {{ic|echo -e}}).}}
\[\033[u\]
+
  
The following example uses these sequences to display the time in the upper right corner:
+
=== PROMPT_COMMAND ===
PS1=">\[\033[s\]\[\033[1;\$((COLUMNS-4))f\]\$(date +%H:%M)\[\033[u\]"
+
  
The environment variable ''COLUMNS'' contains the number of columns of the terminal. The above example substracts 4 from its value in order to justify the five character wide output of ''date'' at the right border.
+
If the {{ic|PROMPT_COMMAND}} variable is set, it will be evaluated right before PS1 is displayed. This can be used to achieve quite powerful effects. For example it can reassign PS1 based on some condition, or perform some operation on your Bash history every time you run a command.
  
===Return value visualisation===
+
{{Warning|PROMPT_COMMAND generally should not be used to print characters directly to the prompt. Characters printed outside of PS1 are not counted by Bash, which will cause it to incorrectly place the cursor and clear characters. Either use PROMPT_COMMAND to set PS1 or look at [[#Embedding commands|embedding commands]].}}
{{Warning| Changing your prompt as described below is buggy on some terminals. You can avoid the bugs by adding a newline \n after the return value symbols.}}
+
  
Add this line if you want to see the return value of the last executed command.
+
=== Escapes between command input and output ===
<nowiki>PROMPT_COMMAND='RET=$?; if [[ $RET -eq 0 ]]; then echo -ne "\033[0;32m$RET\033[0m ;)"; else echo -ne "\033[0;31m$RET\033[0m ;("; fi; echo -n " "'</nowiki>
+
  
It will look like this:
+
You can affect your input text in Bash by not resetting the text properties at the end of your PS1. For example, inserting {{ic|tput blink}} at the end of your PS1 will make your typed commands blink. However this effect will also continue through the command's output since the text properties are not reset when you hit Enter.
<font color="green">0</font><b> ;) </b>harvie@harvie-ntb ~/ $ true
+
<font color="green">0</font><b> ;) </b>harvie@harvie-ntb ~/ $ false
+
<font color="red">1</font><b> ;( </b>harvie@harvie-ntb ~/ $
+
Zero is green and non-zero is red. There is also the smiley indication (replace it with anything you want); so your prompt will smile if the last operation was successful.
+
  
Because terminal emulators like rxvt-unicode use the variable PROMPT_COMMAND to set their window title, it must be altered further when using such terminal.
+
In order to insert escape sequences after you type a command but before the output is displayed, you can trap Bash's DEBUG signal, which is sent right before each command is executed:
<nowiki> printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}" </nowiki>
+
Append the above string to the PROMPT_COMMAND='...' line, and the window title will show user@hostname: /working/directory as intended.
+
  
====Advanced return value visualisation====
+
{{hc|~/.bashrc|
If you want colors, you need to set ''$RED'' and ''$GREEN'' values:
+
<nowiki>trap 'tput sgr0' DEBUG</nowiki>}}
RED='\e[0;31m'
+
GREEN='\e[0;32m'
+
  
You have to specify these values in Bash's configuration files:
+
=== Customizing root prompts ===
{{bc|<nowiki>
+
#return value visualisation
+
PROMPT_COMMAND='RET=$?;'
+
RET_VALUE='$(echo $RET)' #Ret value not colorized - you can modify it.
+
RET_SMILEY='$(if [[ $RET = 0 ]]; then echo -ne "\[$GREEN\];)"; else echo -ne "\[$RED\];("; fi;)'
+
</nowiki>}}
+
  
Then you can use ''$RET_VALUE'' and ''$RET_SMILEY'' variables in the prompt. Note that you need use double quotes:
+
To ensure that you know when you are running as root, you can customize your root prompt to make it clearly stand out (perhaps blinking red?). This is done by customize the Bash prompt as usual but in root's home directory, {{ic|/root}}. Start off by copying the skeleton files {{ic|/etc/skel/.bash_profile}} and {{ic|/etc/skel/.bashrc}} to {{ic|/root}}, then edit {{ic|/root/.bashrc}} as desired.
#prompt
+
PS1="$RET_VALUE $RET_SMILEY : "
+
  
This will give you basic prompt:
+
== Examples ==
0 <font color="green">;)</font> : true
+
0 <font color="green">;)</font> : false
+
1 <font color="red">;(</font> :
+
  
But you will probably want to use ''$RET_VALUE'' or ''$RET_SMILEY'' in your own prompt, like this:
+
=== Colors ===
{{bc|<nowiki>
+
PS1="\[$WHITE\]$RET_VALUE $RET_SMILEY \[$BLUE\]\u\[$RED\]@\[$EBLUE\]\h\[$WHITE\] \W \[$ERED\]\\$\[$EWHITE\] "
+
</nowiki>}}
+
  
Here's an alternative that only include the error status if it is nonzero:
+
{{Tip|{{ic|infocmp}} shows the number of colors {{ic|tput}} works with, for example {{ic|colors#8}}.}}
{{bc|<nowiki>
+
PROMPT_COMMAND='es=$?; [[ $es -eq 0 ]] && unset error || error=$(echo -e "\e[1;41m $es \e[40m")'
+
PS1="${error} ${PS1}"
+
</nowiki>}}
+
  
===Wolfman's===
+
To see the full range of colors your terminal supports, you can use a simple loop with tput (change {{ic|setab}} to {{ic|setaf}} for text foregrounds):
After reading through most of the [http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/index.html Bash Prompt Howto], the author developed a color bash prompt that displays the last 25 characters of the current working directory. This prompt should work well on terminals with a black background. The following code goes in file {{ic|~/.bashrc}}.
+
  
*Add the bash_prompt_command function. If you have a couple directories with long names or start entering a lot of subdirectories, this function will keep the command prompt from wrapping around the screen by displaying at most the last pwdmaxlen characters from the PWD. This code was taken from the ''Bash Prompt Howto''<nowiki>'s</nowiki> section on [http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x783.html Controlling the Size and Appearance of $PWD] and modified to replace the user's home directory with a tilde.
+
{{bc|for C in {0..255}; do
##################################################
+
    tput setab $C
# Fancy PWD display function
+
    echo -n "$C "
##################################################
+
done
# The home directory (HOME) is replaced with a ~
+
tput sgr0
# The last pwdmaxlen characters of the PWD are displayed
+
echo}}
# 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
+
##################################################
+
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=".."
+
    local dir=${PWD##*/}
+
    pwdmaxlen=$(( ( pwdmaxlen < ${#dir} ) ? ${#dir} : pwdmaxlen ))
+
    NEW_PWD=${PWD/#$HOME/\~}
+
    local pwdoffset=$(( ${#NEW_PWD} - pwdmaxlen ))
+
    if [ ${pwdoffset} -gt "0" ]
+
    then
+
        NEW_PWD=${NEW_PWD:$pwdoffset:$pwdmaxlen}
+
        NEW_PWD=${trunc_symbol}/${NEW_PWD#*/}
+
    fi
+
}
+
  
*The next fragment generates the command prompt and various colors are defined. The user's color for the username, hostname, and prompt ($ or #) is set to cyan, and if the user is root (root's UID is always 0), set the color to red. The command prompt is set to a colored version of Arch's default with the NEW_PWD from the last function.
+
If that does not work (and you cannot fix it by setting the [[#Terminfo escape sequences|correct TERM value]]), you can test the different manual escape sequences:
  
:Also, make sure that your color variables are enclosed in double and not single quote marks. Using single quote marks seems to give Bash problems with line wrapping correctly.
+
{{bc|# standard colors
bash_prompt() {
+
for C in {40..47}; do
    case $TERM in
+
    echo -en "\e[${C}m$C "
      xterm*|rxvt*)
+
done
          local TITLEBAR='\[\033]0;\u:${NEW_PWD}\007\]'
+
# high intensity colors
          ;;
+
for C in {100..107}; do
      *)
+
    echo -en "\e[${C}m$C "
          local TITLEBAR=""
+
done
          ;;
+
# 256 colors
    esac
+
for C in {16..255}; do
    local NONE="\[\033[0m\]"   # unsets color to term's fg color
+
     echo -en "\e[48;5;${C}m$C "
   
+
done
    # regular colors
+
echo -e "\e(B\e[m"
    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\]"
+
   
+
    # 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=$W                # user's color
+
    [ $UID -eq "0" ] && UC=$R  # root's color
+
   
+
    PS1="$TITLEBAR ${EMK}[${UC}\u${EMK}@${UC}\h ${EMB}\${NEW_PWD}${EMK}]${UC}\\$ ${NONE}"
+
    # without colors: PS1="[\u@\h \${NEW_PWD}]\\$ "
+
    # extra backslash in front of \$ to make bash colorize the prompt
+
}
+
 
+
*Finally, append this code. This ensures that the NEW_PWD variable will be updated when you cd somewhere else, and it sets the PS1 variable, which contains the command prompt.
+
PROMPT_COMMAND=bash_prompt_command
+
bash_prompt
+
unset bash_prompt
+
 
+
===KitchM's===
+
These prompts offer a little more flash and visual clarity.  Note that the use of red in the root user's prompt should provide ample warning.  That is not to say someone could not use flashing text or arrow to do even more, but these will give you a good starting point.
+
 
+
'''First''', change the default background in your terminal preferences (this example uses Xfce's Terminal program) to #D2D2D2, and the text color to #000000.  The font is listed as DejaVu Sans Mono Book 12.  The cursor color is #00AA00, and the tab activity color is #AF0000.
+
 
+
'''Second''', in ~/.bashrc and right after the PS1= line, enter a new line with the following:
+
PS1='\e[1;33;47m\u \e[1;32;47mon \h \e[1;35;47m\d \@\e[0;0m\n\e[1;34m[dir.= \w] \# > \e[0;0m'
+
And then place a # in front of the first PS1 line to remark it out.
+
 
+
'''Third''', for root user, edit /root/.bashrc in the same manner to include:
+
PS1='\e[1;31;47m\u \e[1;32;47mon \h \e[1;35;47m\d \@\e[0;0m\n\e[1;31m[dir.= \w] \# > \e[0;0m'
+
Do not forget to comment out the old line.
+
 
+
These are double-line prompts, and they should look something like these:
+
 
+
User-
+
<span style="color:#D2D2D2; background:#D2D2D2">                                          </span>
+
<span style="color:#FFFF00; background:#A9A9A9"><b>Username</b></span><span style="color:#00FF00; background:#A9A9A9"><b> on myhost</b></span><span style="color:#FF00FF; background:#A9A9A9"><b> Sun Jan 15 12:30 PM</b></span><span style="color:#D2D2D2; background:#D2D2D2">     </span>
+
<span style="color:#0000FF; background:#D2D2D2"><b>[dir.= /home/username] 1 >                </b> </span>
+
<span style="color:#D2D2D2; background:#D2D2D2">                                          </span>
+
 
+
Root-
+
<span style="color:#D2D2D2; background:#D2D2D2">                                          </span>
+
<span style="color:#FF0000; background:#A9A9A9"><b>Root</b></span><span style="color:#00FF00; background:#A9A9A9"><b> on myhost</b> </span><span style="color:#FF00FF; background:#A9A9A9"><b> Sun Jan 15 12:30 PM</b> </span><span style="color:#D2D2D2; background:#D2D2D2">      </span> 
+
<span style="color:#FF0000; background:#D2D2D2"><b>[dir.= /etc/rc.d] 1 >                    </b> </span>
+
<span style="color:#D2D2D2; background:#D2D2D2">                                          </span>
+
 
+
You will note that the background colors make them easier to read, and the text colors just keep things interesting.  There is a lot of leeway to make them personalized, just with the use of colors.  Enjoy!
+
 
+
==Set window title==
+
[[Xterm]] and many other terminal emulators (including PuTTY) allow you to set the window title using special escape sequences.  You can define the {{ic|<nowiki>${XTERM_TITLE}</nowiki>}} variable as follows, then insert it at the beginning of the prompt to set [[xterm]] title (if available) to directory@user@hostname:
+
 
+
#set xterm title
+
case "$TERM" in
+
  xterm | xterm-color)
+
    XTERM_TITLE='\[\e]0;\W@\u@\H\a\]'
+
  ;;
+
esac
+
 
+
The text between {{ic|0;}} and {{ic|\a}} can be set to anything you like, for example:
+
export PS1='\[\e]0;Welcome to ArchLinux\a\]\$>> '
+
sets the window title to "Welcome to ArchLinux" and displays this simple prompt:
+
{{bc|1=
+
<span style="color: #000">$>></span> <span style="text-decoration: blink;">_</span>
+
 
}}
 
}}
  
==Different colors for text entry and console output==
+
To change the manual escapes from background to foreground, the standard color range is {{ic|30..37}}, the high intensity range is {{ic|90..97}}, and the 48 should be changed to 38 for 256 colors.
If you do not reset the text color at the end of your prompt, both the text you enter and the console text will simply stay in that color. If you want to edit text in a special color but still use the default color for command output, you will need to reset the color after you press enter, but still before any commands get run. You can do this by installing a DEBUG trap in your ~/.bashrc, like this:
+
  
trap 'echo -ne "\e[0m"' DEBUG
+
=== Common capabilities ===
  
==Generalizing colors for all users==
+
The following [[#Terminfo escape sequences|terminfo capabilities]] are useful for prompt customization and are supported by many terminals. '''#1''' and '''#2''' are placeholders for numeric arguments.
If you want to generalize the use of colors for all users in the system, you must remove your {{ic|~/.bashrc}} file, modify the {{ic|/etc/bash.bashrc}} file and create a {{ic|/etc/DIR_COLORS}} file. Here is our possible generalization of the Gentoo color scheme for Arch linux:
+
  
'''/etc/bash.bashrc''':
+
{| class="wikitable"
{{bc|<nowiki># /etc/bash.bashrc
+
! Capability !! Escape sequence !! Description
#
+
|-
# https://wiki.archlinux.org/index.php/Color_Bash_Prompt
+
!colspan="3"| Text attributes
#
+
|-
# This file is sourced by all *interactive* bash shells on startup,
+
| blink || \E[5m || blinking text on
# including some apparently interactive shells such as scp and rcp
+
|-
# that can't tolerate any output.  So make sure this doesn't display
+
| bold || \E[1m || bold text on
# anything or bad things will happen !
+
|-
 +
| dim || \E[2m || dim text on
 +
|-
 +
| rev || \E[7m || reverse video on (switch text/background colors)
 +
|-
 +
| sitm || \E[3m || italic text on
 +
|-
 +
| ritm || \E[23m || italic text off
 +
|-
 +
| smso || \E[7m || highlighted text on
 +
|-
 +
| rmso || \E[27m || highlighted text off
 +
|-
 +
| smul || \E[4m || underlined text on
 +
|-
 +
| rmul || \E[24m || underlined text off
 +
|-
 +
| setab '''#1''' || \E[4'''#1'''m || set background color '''#1''' (0-7)
 +
|-
 +
| setaf '''#1''' || \E[3'''#1'''m || set text color '''#1''' (0-7)
 +
|-
 +
| sgr0 || \E(B\E[m || reset text attributes
 +
|-
 +
!colspan="3"| Cursor movement
 +
|-
 +
| sc || \E7 || save cursor position
 +
|-
 +
| rc || \E8 || restore saved cursor position
 +
|-
 +
| clear || \E[H\E[2J || clear screen and move cursor to top left
 +
|-
 +
| cuu '''#1''' || \E['''#1'''A || move cursor up '''#1''' rows
 +
|-
 +
| cud '''#1''' || \E['''#1'''B || move cursor down '''#1''' rows
 +
|-
 +
| cuf '''#1''' || \E['''#1'''C || move cursor right '''#1''' columns
 +
|-
 +
| cub '''#1''' || \E['''#1'''D || move cursor left '''#1''' columns
 +
|-
 +
| home || \E[H || move cursor to top left
 +
|-
 +
| hpa '''#1''' || \E['''#1'''G || move cursor to column '''#1'''
 +
|-
 +
| vpa '''#1''' || \E['''#1'''d || move cursor to row '''#1''', first column
 +
|-
 +
| cup '''#1''' '''#2''' || \E['''#1''';'''#2'''H || move cursor to row '''#1''', column '''#2'''
 +
|-
 +
!colspan="3"| Removing characters
 +
|-
 +
| dch '''#1''' || \E'''#1'''P || remove '''#1''' characters (like backspacing)
 +
|-
 +
| dl '''#1''' || \E'''#1'''M || remove '''#1''' lines
 +
|-
 +
| ech '''#1''' || \E'''#1'''X || clear '''#1''' characters (without moving cursor)
 +
|-
 +
| ed || \E[J || clear to bottom of screen
 +
|-
 +
| el || \E[K || clear to end of line
 +
|-
 +
| el1 || \E[1K || clear to beginning of line
 +
|}
  
# Test for an interactive shell.  There is no need to set anything
+
=== Visualizing exit codes ===
# past this point for scp and rcp, and it's important to refrain from
+
# outputting anything in those cases.
+
  
if [[ $- != *i* ]] ; then
+
Using the same trick from [[#Embedding commands|embedding commands]] you can delay the interpolation of special Bash variables like {{ic|$?}}. So the following prompt shows the exit code of the previous command:
# Shell is non-interactive. Be done now!
+
return
+
fi
+
  
# Bash won't get SIGWINCH if another process is in the foreground.
+
export PS1="\$? > "
# Enable checkwinsize so that bash will check the terminal size when
+
# or
# it regains control. #65623
+
  export PS1='$? > '
# http://cnswww.cns.cwru.edu/~chet/bash/FAQ (E11)
+
shopt -s checkwinsize
+
  
# Enable history appending instead of overwriting.  #139609
+
<div style="font-family: monospace; white-space: pre; padding: 1em; background-color: black; border: 1px solid #bcd; color: white;">0 > true<br>0 > false<br>1 ></div>
shopt -s histappend
+
  
case ${TERM} in
+
This can be made more interesting using conditionals and functions:
  xterm*|rxvt*|Eterm|aterm|kterm|gnome*)
+
    PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
+
    ;;
+
  screen)
+
    PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'printf "\033_%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
+
    ;;
+
esac
+
  
# fortune is a simple program that displays a pseudorandom message
+
{{bc|<nowiki>exitstatus()
# from a database of quotations at logon and/or logout.
+
{
# Type: "pacman -S fortune-mod" to install it, then uncomment the
+
    if [[ $? == 0 ]]; then
# following lines:
+
        echo ':)'
 +
    else
 +
        echo 'D:'
 +
    fi
 +
}
 +
export PS1='$(exitstatus) > '</nowiki>}}
  
# if [ "$PS1" ]; then
+
<div style="font-family: monospace; white-space: pre; padding: 1em; background-color: black; border: 1px solid #bcd; color: white;">:) > true<br>:) > false<br>D: ></div>
# /usr/bin/fortune
+
# fi
+
  
# Set colorful PS1 only on colorful terminals.
+
=== Positioning the cursor ===
# dircolors --print-database uses its own built-in database
+
# instead of using /etc/DIR_COLORS.  Try to use the external file
+
# first to take advantage of user additions.  Use internal bash
+
# globbing instead of external grep binary.
+
  
# Dynamically modified variables. Do not change them!
+
It is possible to move the cursor around the screen inside of PS1 to make different parts of the prompt appear in different locations. However, to ensure that Bash positions the cursor and output in the right position, you must move the cursor back to the original position after you are done printing elsewhere. This can be done using the tput capabilities {{ic|sc}} and {{ic|rc}} to save and restore the cursor position. The general pattern for a prompt that moves the cursor is
use_color=false
+
# sanitize TERM:
+
safe_term=${TERM//[^[:alnum:]]/?}
+
match_lhs=""
+
  
[[ -f ~/.dir_colors  ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
+
export PS1="\[$(tput sc; ''cursor-moving code'') ''positioned prompt stuff'' $(tput rc)\] ''normal prompt stuff''"
[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
+
[[ -z ${match_lhs}    ]] \
+
&& type -P dircolors >/dev/null \
+
&& match_lhs=$(dircolors --print-database)
+
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true
+
  
if ${use_color} ; then
+
where the entire block of repositioned prompt is wrapped in {{ic|\[ \]}} to prevent Bash from counting it as part of the regular prompt.
# Enable colors for ls, etc.  Prefer ~/.dir_colors #64489
+
if type -P dircolors >/dev/null ; then
+
if [[ -f ~/.dir_colors ]] ; then
+
eval $(dircolors -b ~/.dir_colors)
+
elif [[ -f /etc/DIR_COLORS ]] ; then
+
eval $(dircolors -b /etc/DIR_COLORS)
+
fi
+
fi
+
  
if [[ ${EUID} == 0 ]] ; then
+
==== Right-justified text ====
PS1='\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
+
else
+
PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
+
fi
+
  
alias ls='ls --color=auto'
+
The simplest way to print text on the right side of the screen is to use printf
alias dir='dir --color=auto'
+
alias grep='grep --colour=auto'
+
else
+
if [[ ${EUID} == 0 ]] ; then
+
# show root@ when we do not have colors
+
PS1='\u@\h \W \$ '
+
else
+
PS1='\u@\h \w \$ '
+
fi
+
fi
+
  
PS2='> '
+
{{bc|1=rightprompt()
PS3='> '
+
{
PS4='+ '
+
    printf "%*s" $COLUMNS "right prompt"
 +
}
  
# Try to keep environment pollution down, EPA loves us.
+
export PS1='\[$(tput sc; rightprompt; tput rc)\]left prompt > '
unset use_color safe_term match_lhs
+
}}
 
+
# Try to enable the auto-completion.
+
[ -r /usr/share/bash-completion/bash_completion  ] && . /usr/share/bash-completion/bash_completion
+
 
+
# Try to enable the "Command not found" hook.
+
[ -r /usr/share/doc/pkgfile/command-not-found.bash ] && . /usr/share/doc/pkgfile/command-not-found.bash</nowiki>}}
+
 
+
'''/etc/DIR_COLORS''':
+
{{bc|<nowiki># Configuration file for the color ls utility
+
# This file goes in the /etc directory, and must be world readable.
+
# You can copy this file to .dir_colors in your $HOME directory to override
+
# the system defaults.
+
 
+
# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not
+
# pipes. 'all' adds color characters to all output. 'none' shuts colorization
+
# off.
+
COLOR all
+
 
+
# Extra command line options for ls go here.
+
# Basically these ones are:
+
#  -F = show '/' for dirs, '*' for executables, etc.
+
#  -T 0 = don't trust tab spacing when formatting ls output.
+
OPTIONS -F -T 0
+
 
+
# Below, there should be one TERM entry for each termtype that is colorizable
+
TERM linux
+
TERM console
+
TERM con132x25
+
TERM con132x30
+
TERM con132x43
+
TERM con132x60
+
TERM con80x25
+
TERM con80x28
+
TERM con80x30
+
TERM con80x43
+
TERM con80x50
+
TERM con80x60
+
TERM xterm
+
TERM vt100
+
TERM rxvt
+
TERM rxvt-256color
+
TERM rxvt-cygwin
+
TERM rxvt-cygwin-native
+
TERM rxvt-unicode
+
TERM rxvt-unicode-256color
+
TERM rxvt-unicode256
+
 
+
# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output)
+
EIGHTBIT 1
+
 
+
# Below are the color init strings for the basic file types. A color init
+
# string consists of one or more of the following numeric codes:
+
# Attribute codes:
+
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
+
# 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
+
NORMAL 00 # global default, although everything should be something.
+
FILE 00 # normal file
+
DIR 01;34 # directory
+
LINK 01;36 # symbolic link
+
FIFO 40;33 # pipe
+
SOCK 01;35 # socket
+
BLK 40;33;01 # block device driver
+
CHR 40;33;01 # character device driver
+
 
+
# This is for files with execute permission:
+
EXEC 01;32
+
 
+
# List any file extensions like '.gz' or '.tar' that you would like ls
+
# to colorize below. Put the extension, a space, and the color init string.
+
# (and any comments you want to add after a '#')
+
.cmd 01;32 # executables (bright green)
+
.exe 01;32
+
.com 01;32
+
.btm 01;32
+
.bat 01;32
+
.tar 01;31 # archives or compressed (bright red)
+
.tgz 01;31
+
.arj 01;31
+
.taz 01;31
+
.lzh 01;31
+
.zip 01;31
+
.z  01;31
+
.Z  01;31
+
.gz  01;31
+
.jpg 01;35 # image formats
+
.gif 01;35
+
.bmp 01;35
+
.xbm 01;35
+
.xpm 01;35
+
.tif 01;35</nowiki>}}
+
 
+
===Random quotations at logon===
+
If you want a random quotation at logon (like Slackware) you must install Fortune. Fortune is a simple program that displays a pseudorandom message from a database of quotations at logon and/or logout. Type: "pacman -S fortune-mod" to install it, then uncomment the following lines from our Gentoo-like {{ic|/etc/bash.bashrc}} file:
+
{{bc|<nowiki># if [ "$PS1" ]; then
+
# /usr/bin/fortune
+
# fi</nowiki>}}
+
  
If you want to colorize (brown in this example) the random message from fortune, replace the previous commented text with:
+
<div style="font-family: monospace; white-space: pre; padding: 1em; background-color: black; border: 1px solid #bcd; color: white;">left prompt > <span style="float: right">right prompt</span></div>
{{bc|<nowiki> if [ "$PS1" ]; then
+
echo -e "\e[00;33m$(/usr/bin/fortune)\e[00m"
+
fi</nowiki>}}
+
  
===Colorized [http://www.archlinux.org/news/ Arch Latest news] at logon===
+
This creates a right-justified variable-sized field {{ic|%*s}} and sets its size to the current number of columns of the terminal {{ic|$COLUMNS}}.
If you want to read the latest news from the [http://www.archlinux.org/ Arch Official Website], instead of a random quotation from fortune, replace the following lines from our Gentoo-like {{ic|/etc/bash.bashrc}} file:
+
{{bc|<nowiki># if [ "$PS1" ]; then
+
# /usr/bin/fortune
+
# fi</nowiki>}}
+
with:
+
{{bc|<nowiki>if [ "$PS1" ]; then
+
# The characters "£, §" are used as metacharacters. They should not be encountered in a feed...
+
echo -e "$(echo $(curl --silent http://www.archlinux.org/feeds/news/ | sed -e ':a;N;$!ba;s/\n/ /g') | \
+
sed -e 's/&amp;amp;/\&amp;/g
+
s/&amp;lt;\|&amp;#60;/</g
+
s/&amp;gt;\|&amp;#62;/>/g
+
s/<\/a>/£/g
+
s/href\=\"/§/g
+
s/<title>/\\n\\n\\n  :: \\e[01;31m/g; s/<\/title>/\\e[00m ::\\n/g
+
s/<link>/ [ \\e[01;36m/g; s/<\/link>/\\e[00m ]/g
+
s/<description>/\\n\\n\\e[00;37m/g; s/<\/description>/\\e[00m\\n\\n/g
+
s/<p\( [^>]*\)\?>\|<br\s*\/\?>/\n/g
+
s/<b\( [^>]*\)\?>\|<strong\( [^>]*\)\?>/\\e[01;30m/g; s/<\/b>\|<\/strong>/\\e[00;37m/g
+
s/<i\( [^>]*\)\?>\|<em\( [^>]*\)\?>/\\e[41;37m/g; s/<\/i>\|<\/em>/\\e[00;37m/g
+
s/<u\( [^>]*\)\?>/\\e[4;37m/g; s/<\/u>/\\e[00;37m/g
+
s/<code\( [^>]*\)\?>/\\e[00m/g; s/<\/code>/\\e[00;37m/g
+
s/<a[^§]*§\([^\"]*\)\"[^>]*>\([^£]*\)[^£]*£/\\e[01;31m\2\\e[00;37m \\e[01;34m[\\e[00;37m \\e[04m\1\\e[00;37m\\e[01;34m ]\\e[00;37m/g
+
s/<li\( [^>]*\)\?>/\n \\e[01;34m*\\e[00;37m /g
+
s/<!\[CDATA\[\|\]\]>//g
+
s/\|>\s*<//g
+
s/ *<[^>]\+> */ /g
+
s/[<>£§]//g')\n\n";
+
fi</nowiki>}}
+
that is a small rss escaping script written by the user [https://aur.archlinux.org/account.php?Action=AccountInfo&ID=33208 grufo]. See [https://bbs.archlinux.org/viewtopic.php?id=146850 this thread] for details.
+
  
===Restoring the original /etc/bash.bashrc file===
+
==== Arbitrary positioning ====
If you repent having modified the {{ic|/etc/bash.bashrc}} file, you can always restore the original Arch {{ic|/etc/bash.bashrc}} file and remove the {{ic|/etc/DIR_COLORS}} file. Note that there is not an "official" bash.bashrc: each distribution has its own.
+
Here is the exact copy of the Arch original {{ic|/etc/bash.bashrc}} file.
+
  
'''/etc/bash.bashrc''':
+
The {{ic|cup}} capability moves the cursor to a specific position on the screen, for example {{ic|tput cup 20 5}} moves the cursor to line 20, column 5 (where 0 0 is the top left corner). {{ic|cuu}}, {{ic|cud}}, {{ic|cuf}}, and {{ic|cub}} (up, down, forward, back) move the cursor relative to its current position. For example {{ic|tput cuf 10}} moves the cursor 10 characters to the right. You can use the {{ic|LINES}} and {{ic|COLUMNS}} variables in the arguments to move the cursor relative to the bottom and right edges. For example, to move 10 lines and 5 columns away from the bottom right corner:
{{bc|<nowiki>#
+
# /etc/bash.bashrc
+
#
+
  
# If not running interactively, don't do anything
+
$ tput cup $((LINES - 11)) $((COLUMNS - 6))
[[ $- != *i* ]] && return
+
  
PS1='[\u@\h \W]\$ '
+
=== Customizing the terminal window title ===
PS2='> '
+
PS3='> '
+
PS4='+ '
+
  
case ${TERM} in
+
The terminal window title can be customized in much the same way as the prompt: by printing escape sequences in the shell. Thus it is common for users to include window title customizations in their prompt. Although this is technically a feature of xterm, many modern terminals support it. The escape sequence to use is {{ic|'''ESC''']2;''new title'''''BEL'''}} where {{ic|'''ESC'''}} and {{ic|'''BEL'''}} are the escape and bell characters. Using [[#Bash escape sequences]], changing the title in your prompt looks like
  xterm*|rxvt*|Eterm|aterm|kterm|gnome*)
+
    PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
+
                                                       
+
    ;;
+
  screen)
+
    PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'printf "\033_%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
+
    ;;
+
esac
+
  
[ -r /usr/share/bash-completion/bash_completion  ] && . /usr/share/bash-completion/bash_completion</nowiki>}}
+
export PS1='\[\e]2;''new title''\a\]prompt > '
  
===Original /etc/bash.bashrc from Gentoo===
+
Of course your window title string can include output from [[#Embedding commands|embedding commands]] or variables such as {{ic|$PWD}}, so that the title changes with each command.
The original ''not modified'' Gentoo's {{ic|/etc/bash.bashrc}} file can be found [http://www.jeremysands.com/archlinux/gentoo-bashrc-2008.0 here].
+
  
==See also==
+
== See also ==
* [https://aur.archlinux.org/packages.php?ID=18418 gentoo-bashrc] from [[AUR]]
+
* tput(1)
+
* [http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x405.html Colours and Cursor Movement With tput]
+
  
==External links==
+
* Community examples and screenshots in the Forum thread: [https://bbs.archlinux.org/viewtopic.php?id=50885 What's your PS1?]
* Forum Discussions:
+
* [https://gitweb.gentoo.org/repo/gentoo.git/tree/app-shells/bash/files/bashrc Gentoo's {{ic|/etc/bash/bashrc}}]. See also {{AUR|gentoo-bashrc}}.
** [http://bbs.archlinux.org/viewtopic.php?id=1817 BASH prompt]
+
* {{man|1|tput}}
** [http://bbs.archlinux.org/viewtopic.php?id=50885 What's your PS1?]
+
** [http://wiki.bash-hackers.org/scripting/terminalcodes tput reference on bash-hackers.org]
* http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
+
** [http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x405.html Colours and Cursor Movement With tput]
 +
* [http://xcolors.net/ Nice Xresources color schemes collection]
 +
* [http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html Bash Prompt HOWTO]
 
* [http://gilesorr.com/bashprompt/prompts/index.html Giles Orr's collection of sample prompts]
 
* [http://gilesorr.com/bashprompt/prompts/index.html Giles Orr's collection of sample prompts]
 +
* [http://misc.flogisoft.com/bash/tip_colors_and_formatting Bash tips: Colors and formatting]
 +
* [https://github.com/nojhan/liquidprompt Liquid Prompt — a useful adaptive prompt for Bash & zsh]
 +
* [http://www.askapache.com/linux-unix/bash-power-prompt.html Bash POWER PROMPT]
 +
* [[Wikipedia:ANSI escape code]]

Latest revision as of 10:18, 6 September 2016

Bash has several prompts which can be customized to increase productivity, aesthetic appeal, and nerd cred.

Prompts

Bash has four prompts that can be customized:

  • PS1 is the primary prompt which is displayed before each command, thus it is the one most people customize.
  • PS2 is the secondary prompt displayed when a command needs more input (e.g. a multi-line command).
  • PS3 is not very commonly used. It is the prompt displayed for Bash's select built-in which displays interactive menus. Unlike the other prompts, it does not expand Bash escape sequences. Usually you would customize it in the script where the select is used rather than in your .bashrc.
  • PS4 is also not commonly used. It is displayed when debugging bash scripts to indicate levels of indirection. The first character is repeated to indicate deeper levels.

All of the prompts are customized by setting the corresponding variable to the desired string (usually in ~/.bashrc), for example

export PS2='> '

Techniques

While one can simply set their prompt to a plain string, there are a variety of techniques for making the prompt more dynamic and useful.

Bash escape sequences

When printing the prompt string, Bash looks for certain backslash-escaped characters and will expand them into special strings. For example, \u is expanded into the current username and \A is expanded to the current time. So a PS1 of '\A \u $ ' would be printed like 17:35 username $ .

Check the "PROMPTING" section of the Bash man page for a complete list of escape sequences.

Terminfo escape sequences

Aside from the escape characters recognized by Bash, most terminals recognize special escape sequences that affect the terminal itself rather than printing characters. For example they might change the color of subsequent printed characters, move the cursor to an arbitrary location, or clear the screen. These escape sequences can be somewhat illegible and can vary from terminal to terminal, so they are documented in the terminfo database. To see what capabilities your terminal supports, run

$ infocmp

The capability names (the part before the =) can be looked up in the terminfo man page for a description of what they do. For example, setaf sets the foreground color of whatever text is printed after it. To get the escape code for a capability, you can use the tput command. For example

$ tput setaf 2

prints the escape sequence to set the foreground color to green.

Note: If tput commands are failing for you, ensure that you have set the correct TERM value for your shell. For example, if you have set xterm instead of xterm-256color, tput setaf will only work with color numbers 0-7.

To practically incorporate these capabilities into your prompt, you can use Bash's command substitution and string interpolation. For example

~/.bashrc
GREEN="\[$(tput setaf 2)\]"
RESET="\[$(tput sgr0)\]"

export PS1="${GREEN}my prompt${RESET}> "
my prompt>
Note: Wrapping the tput output in \[ \] is recommended by the Bash man page. This helps Bash ignore non-printable characters so that it correctly calculates the size of the prompt.

ANSI escape sequences

Unfortunately, valid ANSI escape sequences may be missing from your terminal's terminfo database. This is especially common with escape sequences for newer features such as 256 color support. In that case you cannot use tput, you must input the escape sequence manually.

See Wikipedia:ANSI escape code for examples of escape sequences. Every escape sequence starts with a literal escape character, which you can input using the Bash escape sequence \e. So for example,\e[48;5;209m sets the background to a peachy color (if you have 256 color support) and \e[2;2H moves the cursor near the top-left corner of the screen.

In cases where Bash escape sequences are not supported (such as PS3) you can get a literal escape character using Bash's printf builtin:

ESC=$(printf "\e")
PEACH="$ESC[48;5;209m"

Embedding commands

If you want to add the output of some command to your prompt, you might be tempted to use command substitution. For example, to add the amount of free memory to your prompt you might try:

export PS1="$(awk '/MemFree/{print $2}' /proc/meminfo) prompt > "
53718 prompt >
53718 prompt >
53718 prompt >

But this doesn't work; the amount of memory shown is the same every time! This is because the command is run once, when PS1 is first set, and never again. The trick is to simply prevent the substitution either by escaping the $ or by defining it in single quotes—either way it will be substituted when the prompt is actually displayed:

export PS1="\$(awk '/MemFree/{print \$2}' /proc/meminfo) prompt > "
# or
export PS1='$(awk "/MemFree/{print \$2}" /proc/meminfo) prompt > '

To prevent long commands from making your PS1 huge, you can define functions:

free_mem()
{
    awk '/MemFree/{print $2}' /proc/meminfo
}

export PS1='$(free_mem) prompt > '
Note: You can use terminfo/ANSI escape sequences inside substituted functions but not Bash escapes. In particular \[ \] won't work for surrounding non-printable characters. Instead you can use the octal escapes \001 and \002 (e.g. using printf or echo -e).

PROMPT_COMMAND

If the PROMPT_COMMAND variable is set, it will be evaluated right before PS1 is displayed. This can be used to achieve quite powerful effects. For example it can reassign PS1 based on some condition, or perform some operation on your Bash history every time you run a command.

Warning: PROMPT_COMMAND generally should not be used to print characters directly to the prompt. Characters printed outside of PS1 are not counted by Bash, which will cause it to incorrectly place the cursor and clear characters. Either use PROMPT_COMMAND to set PS1 or look at embedding commands.

Escapes between command input and output

You can affect your input text in Bash by not resetting the text properties at the end of your PS1. For example, inserting tput blink at the end of your PS1 will make your typed commands blink. However this effect will also continue through the command's output since the text properties are not reset when you hit Enter.

In order to insert escape sequences after you type a command but before the output is displayed, you can trap Bash's DEBUG signal, which is sent right before each command is executed:

~/.bashrc
trap 'tput sgr0' DEBUG

Customizing root prompts

To ensure that you know when you are running as root, you can customize your root prompt to make it clearly stand out (perhaps blinking red?). This is done by customize the Bash prompt as usual but in root's home directory, /root. Start off by copying the skeleton files /etc/skel/.bash_profile and /etc/skel/.bashrc to /root, then edit /root/.bashrc as desired.

Examples

Colors

Tip: infocmp shows the number of colors tput works with, for example colors#8.

To see the full range of colors your terminal supports, you can use a simple loop with tput (change setab to setaf for text foregrounds):

for C in {0..255}; do
    tput setab $C
    echo -n "$C "
done
tput sgr0
echo

If that does not work (and you cannot fix it by setting the correct TERM value), you can test the different manual escape sequences:

# standard colors
for C in {40..47}; do
    echo -en "\e[${C}m$C "
done
# high intensity colors
for C in {100..107}; do
    echo -en "\e[${C}m$C "
done
# 256 colors
for C in {16..255}; do
    echo -en "\e[48;5;${C}m$C "
done
echo -e "\e(B\e[m"

To change the manual escapes from background to foreground, the standard color range is 30..37, the high intensity range is 90..97, and the 48 should be changed to 38 for 256 colors.

Common capabilities

The following terminfo capabilities are useful for prompt customization and are supported by many terminals. #1 and #2 are placeholders for numeric arguments.

Capability Escape sequence Description
Text attributes
blink \E[5m blinking text on
bold \E[1m bold text on
dim \E[2m dim text on
rev \E[7m reverse video on (switch text/background colors)
sitm \E[3m italic text on
ritm \E[23m italic text off
smso \E[7m highlighted text on
rmso \E[27m highlighted text off
smul \E[4m underlined text on
rmul \E[24m underlined text off
setab #1 \E[4#1m set background color #1 (0-7)
setaf #1 \E[3#1m set text color #1 (0-7)
sgr0 \E(B\E[m reset text attributes
Cursor movement
sc \E7 save cursor position
rc \E8 restore saved cursor position
clear \E[H\E[2J clear screen and move cursor to top left
cuu #1 \E[#1A move cursor up #1 rows
cud #1 \E[#1B move cursor down #1 rows
cuf #1 \E[#1C move cursor right #1 columns
cub #1 \E[#1D move cursor left #1 columns
home \E[H move cursor to top left
hpa #1 \E[#1G move cursor to column #1
vpa #1 \E[#1d move cursor to row #1, first column
cup #1 #2 \E[#1;#2H move cursor to row #1, column #2
Removing characters
dch #1 \E#1P remove #1 characters (like backspacing)
dl #1 \E#1M remove #1 lines
ech #1 \E#1X clear #1 characters (without moving cursor)
ed \E[J clear to bottom of screen
el \E[K clear to end of line
el1 \E[1K clear to beginning of line

Visualizing exit codes

Using the same trick from embedding commands you can delay the interpolation of special Bash variables like $?. So the following prompt shows the exit code of the previous command:

export PS1="\$? > "
# or
export PS1='$? > '
0 > true
0 > false
1 >

This can be made more interesting using conditionals and functions:

exitstatus()
{
    if [[ $? == 0 ]]; then
        echo ':)'
    else
        echo 'D:'
    fi
}
export PS1='$(exitstatus) > '
:) > true
:) > false
D: >

Positioning the cursor

It is possible to move the cursor around the screen inside of PS1 to make different parts of the prompt appear in different locations. However, to ensure that Bash positions the cursor and output in the right position, you must move the cursor back to the original position after you are done printing elsewhere. This can be done using the tput capabilities sc and rc to save and restore the cursor position. The general pattern for a prompt that moves the cursor is

export PS1="\[$(tput sc; cursor-moving code) positioned prompt stuff $(tput rc)\] normal prompt stuff"

where the entire block of repositioned prompt is wrapped in \[ \] to prevent Bash from counting it as part of the regular prompt.

Right-justified text

The simplest way to print text on the right side of the screen is to use printf

rightprompt()
{
    printf "%*s" $COLUMNS "right prompt"
}

export PS1='\[$(tput sc; rightprompt; tput rc)\]left prompt > '
left prompt > right prompt

This creates a right-justified variable-sized field %*s and sets its size to the current number of columns of the terminal $COLUMNS.

Arbitrary positioning

The cup capability moves the cursor to a specific position on the screen, for example tput cup 20 5 moves the cursor to line 20, column 5 (where 0 0 is the top left corner). cuu, cud, cuf, and cub (up, down, forward, back) move the cursor relative to its current position. For example tput cuf 10 moves the cursor 10 characters to the right. You can use the LINES and COLUMNS variables in the arguments to move the cursor relative to the bottom and right edges. For example, to move 10 lines and 5 columns away from the bottom right corner:

$ tput cup $((LINES - 11)) $((COLUMNS - 6))

Customizing the terminal window title

The terminal window title can be customized in much the same way as the prompt: by printing escape sequences in the shell. Thus it is common for users to include window title customizations in their prompt. Although this is technically a feature of xterm, many modern terminals support it. The escape sequence to use is ESC]2;new titleBEL where ESC and BEL are the escape and bell characters. Using #Bash escape sequences, changing the title in your prompt looks like

export PS1='\[\e]2;new title\a\]prompt > '

Of course your window title string can include output from embedding commands or variables such as $PWD, so that the title changes with each command.

See also