Difference between revisions of "Bash/Prompt customization"

From ArchWiki
Jump to: navigation, search
(/etc/skel/.bashrc: New paragraph)
m (See also: man page link)
 
(211 intermediate revisions by 49 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]]
{{Article summary start}}
+
[[zh-CN:Color Bash Prompt]]
{{Article summary text|Discussing and improving Bash graphical customisations.}}
+
{{Related articles start}}
{{Article summary heading|Related}}
+
{{Related|Bash}}
{{Article summary wiki|Environment Variables}}
+
{{Related|Environment variables}}
{{Article summary wiki|Bash}}
+
{{Related|Git#Git prompt}}
{{Article summary end}}
+
{{Related articles end}}
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. See [https://bbs.archlinux.org/viewtopic.php?id=50885 this thread] for more informations and examples.
+
Bash has several prompts which can be customized to increase productivity, aesthetic appeal, and nerd cred.
  
=A well-established Bash color prompt=
+
== Prompts ==
  
What follows is a well-proven way to color the Bash prompt. It is the most widespread Bash color scheme in the GNU/Linux world. Here is a preview of how it will appear:
+
Bash has four prompts that can be customized:
  
<div style="font-family: monospace; white-space: pre; overflow: auto; margin: 1em 3em; padding: 1em; border: 3px solid #bcd; background-color: black; color: #aaa;"><nowiki>I am two with nature.
+
* {{ic|PS1}} is the primary prompt which is displayed before each command, thus it is the one most people customize.
-- Woody Allen</nowiki>
+
* {{ic|PS2}} is the secondary prompt displayed when a command needs more input (e.g. a multi-line command).
<span style="color: #0a0; font-weight: bold;">andy@alba</span> <span style="color: #55f; font-weight: bold;">~ $</span> ls
+
* {{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}}.
<span style="color: #55f; font-weight: bold;">Desktop  Documents  Music</span>  public.desktop
+
* {{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.
<span style="color: #0a0; font-weight: bold;">andy@alba</span> <span style="color: #55f; font-weight: bold;">~ $</span> I\ will\ try\ to\ type\ a\ wrong\ command...
+
bash: I will try to type a wrong command...: command not found
+
<span style="color: #0a0; font-weight: bold;">andy@alba</span> <span style="color: #55f; font-weight: bold;">~</span> <span style="color: #a00; font-weight: bold;">:(</span> <span style="color: #55f; font-weight: bold;">$</span> echo 'Hello world!'
+
Hello world!
+
<span style="color: #0a0; font-weight: bold;">andy@alba</span> <span style="color: #55f; font-weight: bold;">~ $</span> <span style="text-decoration: blink;">_</span>
+
</div>
+
  
==Installation==
+
All of the prompts are customized by setting the corresponding variable to the desired string (usually in {{ic|~/.bashrc}}), for example
  
It's a '''generalized scheme for all users''', so you should start removing your {{ic|~/.bashrc}} file and then modify the {{ic|/etc/bash.bashrc}} file and create a {{ic|/etc/DIR_COLORS}} file (but {{ic|~/.bashrc}} and {{ic|/etc/bash.bashrc}} [[Color_Bash_Prompt#Example_of_cohabitation_of_.2Fetc.2Fbash.bashrc_and_.7E.2F.bashrc|can also cohabitate]]). Here is our possible version of this scheme for Arch (originally this scheme was created for Gentoo, but here are some important additions).
+
export PS2='> '
  
===/etc/bash.bashrc===
+
== Techniques ==
{{bc|<nowiki># /etc/bash.bashrc
+
#
+
# https://wiki.archlinux.org/index.php/Color_Bash_Prompt
+
#
+
# This file is sourced by all *interactive* bash shells on startup,
+
# including some apparently interactive shells such as scp and rcp
+
# that can't tolerate any output. So make sure this doesn't display
+
# anything or bad things will happen !
+
  
# Test for an interactive shell. There is no need to set anything
+
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.
# past this point for scp and rcp, and it's important to refrain from
+
# outputting anything in those cases.
+
  
# If not running interactively, don't do anything!
+
=== Bash escape sequences ===
[[ $- != *i* ]] &amp;&amp; return
+
  
# Bash won't get SIGWINCH if another process is in the foreground.
+
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'' $ }}.
# Enable checkwinsize so that bash will check the terminal size when
+
# it regains control.
+
# http://cnswww.cns.cwru.edu/~chet/bash/FAQ (E11)
+
shopt -s checkwinsize
+
  
# Enable history appending instead of overwriting.
+
Check the "PROMPTING" section of the Bash man page for a complete list of escape sequences.
shopt -s histappend
+
  
case ${TERM} in
+
=== Terminfo escape sequences ===
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
+
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
# from a database of quotations at logon and/or logout.
+
# Type: "pacman -S fortune-mod" to install it, then uncomment the
+
# following line:
+
  
# [[ "$PS1" ]] &amp;&amp; /usr/bin/fortune
+
$ infocmp
  
# Set colorful PS1 only on colorful terminals.
+
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
# 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!
+
$ tput setaf 2
use_color=false
+
# sanitize TERM:
+
safe_term=${TERM//[^[:alnum:]]/?}
+
match_lhs=""
+
  
[[ -f ~/.dir_colors ]] &amp;&amp; match_lhs="${match_lhs}$(&lt;~/.dir_colors)"
+
prints the escape sequence to set the foreground color to green.
[[ -f /etc/DIR_COLORS ]] &amp;&amp; match_lhs="${match_lhs}$(&lt;/etc/DIR_COLORS)"
+
[[ -z ${match_lhs} ]] \
+
&amp;&amp; type -P dircolors &gt;/dev/null \
+
&amp;&amp; match_lhs=$(dircolors --print-database)
+
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] &amp;&amp; use_color=true
+
  
if ${use_color} ; then
+
{{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.}}
  
# Enable colors for ls, etc. Prefer ~/.dir_colors
+
To practically incorporate these capabilities into your prompt, you can use Bash's command substitution and string interpolation. For example
if type -P dircolors &gt;/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
+
  
# create a red "sad" smile if the previous command had returned an error
+
{{hc|~/.bashrc|<nowiki>GREEN="\[$(tput setaf 2)\]"
sadness='$([[ $? != 0 ]] &amp;&amp; echo "\[\033[01;31m\]:(\[\033[01;34m\] ")'
+
RESET="\[$(tput sgr0)\]"
  
if [[ ${EUID} == 0 ]] ; then
+
export PS1="${GREEN}my prompt${RESET}> "</nowiki>}}
PS1="\[\033[01;31m\]\h\[\033[01;34m\] \W $sadness\$\[\033[00m\] "
+
<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>
else
+
PS1="\[\033[01;32m\]\u@\h\[\033[01;34m\] \w $sadness\$\[\033[00m\] "
+
fi
+
  
alias ls="ls --color=auto"
+
{{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.}}
alias dir="dir --color=auto"
+
alias grep="grep --colour=auto"
+
  
else
+
=== ANSI escape sequences ===
  
# create a "sad" smile if the previous command had returned an error
+
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.
sadness='$([[ $? != 0 ]] &amp;&amp; echo ":( ")'
+
  
if [[ ${EUID} == 0 ]] ; then
+
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.
# show root@ when we do not have colors
+
PS1="\u@\h \W $sadness\$ "
+
else
+
PS1="\u@\h \w $sadness\$ "
+
fi
+
  
fi
+
In cases where Bash escape sequences are not supported (such as PS3) you can get a literal escape character using Bash's printf builtin:
  
PS2="&gt; "
+
ESC=$(printf "\e")
PS3="&gt; "
+
PEACH="$ESC[48;5;209m"
PS4="+ "
+
  
# Try to keep environment pollution down, EPA loves us.
+
=== Embedding commands ===
unset use_color safe_term match_lhs sadness
+
  
# Try to enable the auto-completion (type: "pacman -S bash-completion" to install it).
+
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:
[ -r /usr/share/bash-completion/bash_completion ] &amp;&amp; . /usr/share/bash-completion/bash_completion
+
{{hc|1=export PS1="$(awk '/MemFree/{print $2}' /proc/meminfo) prompt > "|2=53718 prompt >
 +
53718 prompt >
 +
53718 prompt >}}
  
# Try to enable the "Command not found" hook ("pacman -S pkgfile" to install it).
+
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:
# See also: https://wiki.archlinux.org/index.php/Bash#The_.22command_not_found.22_hook
+
[ -r /usr/share/doc/pkgfile/command-not-found.bash ] &amp;&amp; . /usr/share/doc/pkgfile/command-not-found.bash</nowiki>}}
+
  
===/etc/DIR_COLORS===
+
export PS1="\$(awk '/MemFree/{print \$2}' /proc/meminfo) prompt > "
<pre style="max-height: 400px; overflow:auto;"># Configuration file for the color ls utility
+
# or
# This file goes in the /etc directory, and must be world readable.
+
export PS1='$(awk "/MemFree/{print \$2}" /proc/meminfo) prompt > '
# 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
+
To prevent long commands from making your PS1 huge, you can define functions:
# pipes. 'all' adds color characters to all output. 'none' shuts colorization
+
# off.
+
COLOR all
+
  
# Extra command line options for ls go here.
+
{{bc|1=free_mem()
# Basically these ones are:
+
{
#  -F = show '/' for dirs, '*' for executables, etc.
+
    awk '/MemFree/{print $2}' /proc/meminfo
#  -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
+
export PS1='$(free_mem) prompt > '}}
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)
+
{{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}}).}}
EIGHTBIT 1
+
  
# Below are the color init strings for the basic file types. A color init
+
=== PROMPT_COMMAND ===
# 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:
+
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.
EXEC 01;32
+
  
# List any file extensions like '.gz' or '.tar' that you would like ls
+
{{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]].}}
# 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</pre>
+
  
===/etc/skel/.bashrc===
+
=== Escapes between command input and output ===
  
This tip shows you how to use {{ic|/etc/skel}} directory to ensure that all new users on your system get the same initial settings.
+
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.
  
The {{ic|/etc/skel}} directory is the directory used by {{ic|useradd}} to create the default settings in a new user's home directory.
+
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:
  
To change the location of {{ic|/etc/skel}}, edit {{ic|/etc/default/useradd}}.
+
{{hc|~/.bashrc|
 +
<nowiki>trap 'tput sgr0' DEBUG</nowiki>}}
  
{{bc|<nowiki># useradd defaults file
+
=== Customizing root prompts ===
GROUP=100
+
HOME=/home
+
INACTIVE=-1
+
EXPIRE=  
+
SHELL=/bin/bash
+
SKEL=/etc/skel</nowiki>}}
+
  
Typically files included in {{ic|/etc/skel}} are .rc files for shell initialization, but you could also include a public_html directory, a custom dircolors file, or anything else.
+
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.
  
{{bc|<nowiki>% ls -A /etc/skel
+
== Examples ==
.bash_profile  .bashrc  .maildir  .screenrc  .tcsh.config</nowiki>}}
+
  
For more information on customizing the {{ic|/etc/skel}} directory, type: {{ic|$ man useradd}}. See also: [http://www.gentoo.org/news/en/gwn/20031222-newsletter.xml http://www.gentoo.org/news/en/gwn/20031222-newsletter.xml].
+
=== Colors ===
  
Now, the {{ic|/etc/skel/.bashrc}} file is the {{ic|.bashrc}} file copyied into the home directory of each new user. It will look something like this:
+
{{Tip|{{ic|infocmp}} shows the number of colors {{ic|tput}} works with, for example {{ic|colors#8}}.}}
  
{{bc|<nowiki>#
+
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):
# ~/.bashrc
+
#
+
  
# If not running interactively, don't do anything
+
{{bc|for C in {0..255}; do
[[ $- != *i* ]] &amp;&amp; return
+
    tput setab $C
 +
    echo -n "$C "
 +
done
 +
tput sgr0
 +
echo}}
  
alias ls='ls --color=auto'
+
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:
PS1='[\u@\h \W]\$ '</nowiki>}}
+
  
As you can see, the {{ic|PS1}} variable (i.e.: the prompt) is overwritten. So, if you had previously created a color prompt through the {{ic|/etc/bash.bashrc}} file, each new user, to see it, should delete the line
+
{{bc|# 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"
 +
}}
  
{{bc|<nowiki>PS1='[\u@\h \W]\$ '</nowiki>}}
+
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.
  
Accordingly, if you want to grant to new users to have the same {{ic|PS1}}, you should delete that line from your {{ic|/etc/skel/.bashrc}} file.
+
=== Common capabilities ===
  
==Example of cohabitation of /etc/bash.bashrc and ~/.bashrc==
+
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.
  
{{ic|~/.bashrc}} and {{ic|/etc/bash.bashrc}} can also cohabitate. Here is a possible example of a typical Arch user's {{ic|~/.bashrc}} file which can cohabit with the {{ic|/etc/bash.bashrc}} file proposed here, valid for all users. The output will remain coloured.
+
{| class="wikitable"
 +
! Capability !! Escape sequence !! Description
 +
|-
 +
!colspan="3"| 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'''#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
 +
|}
  
{{bc|<nowiki>#
+
=== Visualizing exit codes ===
# ~/.bashrc
+
#
+
  
# If not running interactively, don't do anything
+
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:
[[ $- != *i* ]] &amp;&amp; return
+
  
# pacman/yaourt aliases
+
export PS1="\$? > "
alias pac="sudo /usr/bin/pacman -S" # default action - install one or more packages
+
# or
alias paca="/usr/bin/yaourt -S" # default yaourt action - install one or more packages including AUR
+
export PS1='$? > '
alias pacu="/usr/bin/yaourt -Syua" # '[u]pdate' - upgrade all packages to their newest version
+
alias pacr="sudo /usr/bin/pacman -Rs" # '[r]emove' - uninstall one or more packages
+
alias pacs="/usr/bin/pacman -Ss" # '[s]earch' - search for a package using one or more keywords
+
alias pacys="/usr/bin/yaourt -Ss" # '[y]aourt [s]earch' - search for a package or a PKGBUILD using one or more keywords
+
alias paci="/usr/bin/yaourt -Si" # '[i]nfo' - show information about a package
+
alias paclo="/usr/bin/pacman -Qdt" # '[l]ist [o]rphans' - list all packages which are orphaned
+
alias pacc="sudo /usr/bin/pacman -Scc" # '[c]lean cache' - delete all not currently installed package files
+
alias paclf="/usr/bin/pacman -Ql" # '[f]iles' - list all files installed by a given package</nowiki>}}
+
  
==Random quotations at logon==
+
<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>
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 {{ic|pacman -S fortune-mod}} to install it, then uncomment the following line from our {{ic|/etc/bash.bashrc}} file:
+
{{bc|<nowiki># [[ "$PS1" ]] &amp;&amp; /usr/bin/fortune</nowiki>}}
+
  
If you want to colorize (brown in this example) the random message from fortune, replace the previous commented text with:
+
This can be made more interesting using conditionals and functions:
{{bc|<nowiki>[[ "$PS1" ]] &amp;&amp; echo -e "\e[00;33m$(/usr/bin/fortune)\e[00m"</nowiki>}}
+
  
==Colorized [http://www.archlinux.org/news/ Arch latest news] at logon==
+
{{bc|<nowiki>exitstatus()
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 {{ic|/etc/bash.bashrc}} file:
+
{
{{bc|<nowiki># fortune is a simple program that displays a pseudorandom message
+
    if [[ $? == 0 ]]; then
# from a database of quotations at logon and/or logout.
+
        echo ':)'
# Type: "pacman -S fortune-mod" to install it, then uncomment the
+
    else
# following line:
+
        echo 'D:'
 +
    fi
 +
}
 +
export PS1='$(exitstatus) > '</nowiki>}}
  
# [[ "$PS1" ]] &amp;&amp; /usr/bin/fortune</nowiki>}}
+
<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>
with:
+
{{bc|<nowiki># Arch latest news
+
  
if [ "$PS1" ]; then
+
=== Positioning the cursor ===
# The characters "&pound;, &sect;" are used as metacharacters. They should not be encountered in a feed...
+
echo -e "$(echo $(curl --silent https://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;/&lt;/g
+
s/&amp;gt;\|&amp;#62;/&gt;/g
+
s/&lt;\/a&gt;/&pound;/g
+
s/href\=\"/&sect;/g
+
s/&lt;title&gt;/\\n\\n\\n  :: \\e[01;31m/g; s/&lt;\/title&gt;/\\e[00m ::\\n/g
+
s/&lt;link&gt;/ [ \\e[01;36m/g; s/&lt;\/link&gt;/\\e[00m ]/g
+
s/&lt;description&gt;/\\n\\n\\e[00;37m/g; s/&lt;\/description&gt;/\\e[00m\\n\\n/g
+
s/&lt;p\( [^&gt;]*\)\?&gt;\|&lt;br\s*\/\?&gt;/\n/g
+
s/&lt;b\( [^&gt;]*\)\?&gt;\|&lt;strong\( [^&gt;]*\)\?&gt;/\\e[01;30m/g; s/&lt;\/b&gt;\|&lt;\/strong&gt;/\\e[00;37m/g
+
s/&lt;i\( [^&gt;]*\)\?&gt;\|&lt;em\( [^&gt;]*\)\?&gt;/\\e[41;37m/g; s/&lt;\/i&gt;\|&lt;\/em&gt;/\\e[00;37m/g
+
s/&lt;u\( [^&gt;]*\)\?&gt;/\\e[4;37m/g; s/&lt;\/u&gt;/\\e[00;37m/g
+
s/&lt;code\( [^&gt;]*\)\?&gt;/\\e[00m/g; s/&lt;\/code&gt;/\\e[00;37m/g
+
s/&lt;a[^&sect;]*&sect;\([^\"]*\)\"[^&gt;]*&gt;\([^&pound;]*\)[^&pound;]*&pound;/\\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/&lt;li\( [^&gt;]*\)\?&gt;/\n \\e[01;34m*\\e[00;37m /g
+
s/&lt;!\[CDATA\[\|\]\]&gt;//g
+
s/\|&gt;\s*&lt;//g
+
s/ *&lt;[^&gt;]\+&gt; */ /g
+
s/[&lt;&gt;&pound;&sect;]//g')\n\n";
+
fi</nowiki>}}
+
that is a small and coloured 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.
+
  
===Variations on a theme===
+
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
  
====From Arch Forum====
+
export PS1="\[$(tput sc; ''cursor-moving code'') ''positioned prompt stuff'' $(tput rc)\] ''normal prompt stuff''"
Here is an unicode variation of our {{ic|/etc/bash.bashrc}} file based on [https://bbs.archlinux.org/viewtopic.php?pid=1068202#p1068202 what wrote the user JeSuisNerd and others]. Here is a preview of how it will appear:
+
  
<div style="font-family: monospace; white-space: pre; overflow: auto; margin: 1em 3em; padding: 1em; border: 3px solid #bcd; background-color: black; color: #aaa;"><nowiki>I am two with nature.
+
where the entire block of repositioned prompt is wrapped in {{ic|\[ \]}} to prevent Bash from counting it as part of the regular prompt.
-- Woody Allen</nowiki>
+
┌─[<span style="color: #f90;">andy</span>@<span style="color: #5fc;">alba</span>]─[<span style="color: #0c0;">~</span>]
+
└──╼ ls
+
<span style="color: #55f; font-weight: bold;">Desktop  Documents  Music</span>  public.desktop
+
┌─[<span style="color: #f90;">andy</span>@<span style="color: #5fc;">alba</span>]─[<span style="color: #0c0;">~</span>]
+
└──╼ I\ will\ try\ to\ type\ a\ wrong\ command...
+
bash: I will try to type a wrong command...: command not found
+
┌─[<span style="color: #a00;">✗</span>]─[<span style="color: #f90;">andy</span>@<span style="color: #5fc;">alba</span>]─[<span style="color: #0c0;">~</span>]
+
└──╼ echo 'Hello world!'
+
Hello world!
+
┌─[<span style="color: #f90;">andy</span>@<span style="color: #5fc;">alba</span>]─[<span style="color: #0c0;">~</span>]
+
└──╼ <span style="text-decoration: blink;">_</span>
+
</div>
+
  
'''Note:''' '''Some unicode symbols (like <span style="color: #a00;">✗</span> and ╼) are not well supported in some terminals''' (in linux console, for example), so this prompt will appear a bit different depending on where is displayed. If you want to know the unicode representation of a plain text, [http://0xcc.net/jsescape/ here] you have a little plain text converter.
+
==== Right-justified text ====
  
And finally here is the {{ic|/etc/bash.bashrc}} file:
+
The simplest way to print text on the right side of the screen is to use printf
  
<pre style="max-height: 400px; overflow:auto;"># /etc/bash.bashrc
+
{{bc|1=rightprompt()
#
+
{
# https://wiki.archlinux.org/index.php/Color_Bash_Prompt
+
    printf "%*s" $COLUMNS "right prompt"
#
+
}
# This file is sourced by all *interactive* bash shells on startup,
+
# including some apparently interactive shells such as scp and rcp
+
# that can't tolerate any output. So make sure this doesn't display
+
# anything or bad things will happen !
+
  
# Test for an interactive shell. There is no need to set anything
+
export PS1='\[$(tput sc; rightprompt; tput rc)\]left prompt > '
# past this point for scp and rcp, and it's important to refrain from
+
# outputting anything in those cases.
+
 
+
# If not running interactively, don't do anything!
+
[[ $- != *i* ]] &amp;&amp; return
+
 
+
# Bash won't get SIGWINCH if another process is in the foreground.
+
# Enable checkwinsize so that bash will check the terminal size when
+
# it regains control.
+
# http://cnswww.cns.cwru.edu/~chet/bash/FAQ (E11)
+
shopt -s checkwinsize
+
 
+
# Enable history appending instead of overwriting.
+
shopt -s histappend
+
 
+
case ${TERM} in
+
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
+
# from a database of quotations at logon and/or logout.
+
# Type: "pacman -S fortune-mod" to install it, then uncomment the
+
# following line:
+
 
+
# [[ "$PS1" ]] &amp;&amp; /usr/bin/fortune
+
 
+
# Set colorful PS1 only on colorful terminals.
+
# 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!
+
use_color=false
+
# sanitize TERM:
+
safe_term=${TERM//[^[:alnum:]]/?}
+
match_lhs=""
+
 
+
[[ -f ~/.dir_colors ]] &amp;&amp; match_lhs="${match_lhs}$(&lt;~/.dir_colors)"
+
[[ -f /etc/DIR_COLORS ]] &amp;&amp; match_lhs="${match_lhs}$(&lt;/etc/DIR_COLORS)"
+
[[ -z ${match_lhs} ]] \
+
&amp;&amp; type -P dircolors &gt;/dev/null \
+
&amp;&amp; match_lhs=$(dircolors --print-database)
+
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] &amp;&amp; use_color=true
+
 
+
if ${use_color} ; then
+
 
+
# Enable colors for ls, etc. Prefer ~/.dir_colors
+
if type -P dircolors &gt;/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
+
 
+
# create a red "X" symbol if the previous command had returned an error
+
sadness='$([[ $? != 0 ]] &amp;&amp; echo "[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200")'
+
 
+
# https://bbs.archlinux.org/viewtopic.php?pid=1068202#p1068202
+
if [[ ${EUID} == 0 ]] ; then
+
PS1="\[\033[0;37m\]\342\224\214\342\224\200$sadness[\[\033[0;31m\]\h\[\033[0;37m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;37m\]]\n\[\033[0;37m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]"
+
else
+
PS1="\[\033[0;37m\]\342\224\214\342\224\200$sadness[\[\033[0;33m\]\u\[\033[0;37m\]@\[\033[0;96m\]\h\[\033[0;37m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;37m\]]\n\[\033[0;37m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]"
+
fi
+
 
+
PS2="\342\225\276\342\224\200\342\224\200\342\225\274 "
+
 
+
alias ls="ls --color=auto"
+
alias dir="dir --color=auto"
+
alias grep="grep --colour=auto"
+
 
+
else
+
 
+
# create a "sad" smile if the previous command had returned an error
+
sadness='$([[ $? != 0 ]] &amp;&amp; echo ":( ")'
+
 
+
if [[ ${EUID} == 0 ]] ; then
+
# show root@ when we do not have colors
+
PS1="\u@\h \W $sadness\$ "
+
else
+
PS1="\u@\h \w $sadness\$ "
+
fi
+
 
+
PS2="&gt; "
+
 
+
fi
+
 
+
PS3="&gt; "
+
PS4="+ "
+
 
+
# Try to keep environment pollution down, EPA loves us.
+
unset use_color safe_term match_lhs sadness
+
 
+
# Try to enable the auto-completion (type: "pacman -S bash-completion" to install it).
+
[ -r /usr/share/bash-completion/bash_completion ] &amp;&amp; . /usr/share/bash-completion/bash_completion
+
 
+
# Try to enable the "Command not found" hook ("pacman -S pkgfile" to install it).
+
# See also: https://wiki.archlinux.org/index.php/Bash#The_.22command_not_found.22_hook
+
[ -r /usr/share/doc/pkgfile/command-not-found.bash ] &amp;&amp; . /usr/share/doc/pkgfile/command-not-found.bash</pre>
+
 
+
==Restoring the original /etc/bash.bashrc file==
+
If you repent having modified the {{ic|/etc/bash.bashrc}} file, you can always restore the original Arch {{ic|/etc/bash.bashrc}} file from the [[ bash ]] package and remove the {{ic|/etc/DIR_COLORS}} file. Note that there is not an "official" bash.bashrc: each distribution has its own.
+
 
+
==Original /etc/bash.bashrc from Gentoo==
+
The original ''not modified'' Gentoo's {{ic|/etc/bash.bashrc}} file can be found [http://www.jeremysands.com/archlinux/gentoo-bashrc-2008.0 here].
+
 
+
=Step by step=
+
 
+
If you want to create a style all your own, you can take a look at these tips. [https://bbs.archlinux.org/viewtopic.php?id=50885 This thread] could give you more informations and examples.
+
 
+
==Basic prompts==
+
The following settings are useful for distinguishing the root prompt from non-root users.
+
 
+
*Edit Bash's personal configuration file:
+
$ nano ~/.bashrc
+
 
+
*Comment out the default prompt:
+
#PS1='[\u@\h \W]\$ '
+
 
+
*Add the following green 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: #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:
+
# 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===
+
*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.
+
 
+
The string above contains color-set escape sequences (start coloring: \[\e[color\], end coloring: \[\e[m\]) and information placeholders:
+
 
+
* \u - Username. The original prompt also has \h, which prints the host name.
+
* \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.
+
 
+
*A red and blue 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: #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.
+
 
+
Once you have made your changes to .bashrc, to execute your changes:
+
$ source ~/.bashrc
+
 
+
==Advanced prompts==
+
 
+
===Load/Mem Status for 256colors===
+
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.
+
 
+
This is for '''256 color terminals''', which is where the '''\033[38;5;22m''' terminal escapes come from. 
+
{{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"'
+
<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>
  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===
+
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}}.
Add this to your Bash file(s) to define colors for prompt and commands:
+
{{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/>
+
==== Arbitrary positioning ====
Or if you prefer color names you will know how to spell without a special decoder ring and want high intensity colors:
+
{{bc|<nowiki># Reset
+
Color_Off='\e[0m'      # Text Reset
+
  
# Regular Colors
+
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:
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
+
$ tput cup $((LINES - 11)) $((COLUMNS - 6))
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
+
=== Customizing the terminal window title ===
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
+
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
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
+
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
+
BIBlack='\e[1;90m'      # Black
+
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
+
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:
+
$ echo -e "${txtblu}test"
+
<font color='blue'>test</font>
+
$ echo -e "${bldblu}test"
+
<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):
+
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.
+
 
+
===Prompt escapes===
+
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===
+
The following sequence sets the cursor position:
+
\[\033[<row>;<column>f\]
+
 
+
The current cursor position can be saved using:
+
\[\033[s\]
+
 
+
To restore a position, use the following sequence:
+
\[\033[u\]
+
 
+
The following example uses these sequences to display the time in the upper right corner:
+
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.
+
 
+
===Return value visualisation===
+
{{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.
+
<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:
+
<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.
+
<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====
+
If you want colors, you need to set ''$RED'' and ''$GREEN'' values:
+
RED='\e[0;31m'
+
GREEN='\e[0;32m'
+
 
+
You have to specify these values in Bash's configuration files:
+
{{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:
+
#prompt
+
PS1="$RET_VALUE $RET_SMILEY : "
+
 
+
This will give you basic prompt:
+
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:
+
{{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:
+
{{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===
+
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.
+
##################################################
+
# 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
+
##################################################
+
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.
+
 
+
: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.
+
bash_prompt() {
+
    case $TERM in
+
      xterm*|rxvt*)
+
          local TITLEBAR='\[\033]0;\u:${NEW_PWD}\007\]'
+
          ;;
+
      *)
+
          local TITLEBAR=""
+
          ;;
+
    esac
+
    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\]"
+
   
+
    # 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==
+
export PS1='\[\e]2;''new title''\a\]prompt > '
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
+
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.
  
==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