Color Bash Prompt
From ArchWiki
| i18n |
|---|
| English |
| Español |
| Italiano |
Contents |
Summary
There are a variety possibilities for your bash prompt, and customizing it will help you be more productive at the command line. You can add additional information to your prompt, or you can simply color it to make the prompt stand out.
Basic Prompts
The following settings are useful for distinguishing the root prompt from non-root users:
Green for regular users:
export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
Set the above PS1 variable in ~/.bashrc and export it.
Red for root:
export PS1='\[\e[1;31m\][\u@\h \W]\$\[\e[0m\] '
Set the above PS1 variable in /root/.bashrc and export it.
Distinct root and non-root Prompts
Use 2 separate config files; one for root (/root/.bash_profile), and one for normal user (~/.bashrc):
vim ~/.bashrc
Comment out the default PS1:
#PS1='[\u@\h \W]\$ '
Use the following prompt for normal user:
PS1='\[\e[0;32m\]\u \[\e[1;34m\]\w \[\e[1;32m\]\$ \[\e[1;37m\] '
It features username in green, working directory in bright blue, a bright green $ prompt, and bright white text-type.
Edit root prompt:
sudo vim /root/.bash_profile
Comment out default:
#PS1='[\u@\h \W]\$ '
Use the following prompt for root:
PS1='\[\e[0;31m\]\u \[\e[1;34m\]\w \[\e[0;31m\]\$ \[\e[0;32m\] '
It features username 'root' in red, working directory in bright blue, a red '#' for su designation, and text-typing in a nasty, matrix-like, Type-O-Negative green. ;)
Here is the bash color code:
Black 0;30 Dark Gray 1;30 Blue 0;34 Light Blue 1;34 Green 0;32 Light Green 1;32 Cyan 0;36 Light Cyan 1;36 Red 0;31 Light Red 1;31 Purple 0;35 Light Purple 1;35 Brown 0;33 Yellow 1;33 Light Gray 0;37 White 1;37
Replace digit 0 with 1 to get bright color version! Experiment as desired, and see bash manpage excerpt below to further customize backslash-escaped special characters.
Tip:
\[ begins a sequence of non-printing characters \] ends a sequence of non-printing characters
Customize your Bash prompt further
- Edit your ~/.bashrc by commenting out the default Arch prompt:
# PS1='[\u@\h \W]\$ '
- Add the following entries to your ~/.bashrc
BLUE=`tput setf 1` GREEN=`tput setf 2` CYAN=`tput setf 3` RED=`tput setf 4` MAGENTA=`tput setf 5` YELLOW=`tput setf 6` WHITE=`tput setf 7` PS1='\[$GREEN\]\u@\h \[$BLUE\]\w/\[$GREEN\] \$\[$WHITE\] '
The \[ and \] are necessary to not get line-wrapping problems on the terminal.
Then do:
source ~/.bashrc
You may wish to edit your /root/.bashrc with a similar set of entries, perhaps with RED to indicate \u.
the various \x's (ripped from bash 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).
Set xterm window title
Add this code fragment to you .bashrc
#set xterm title
case "$TERM" in
xterm | xterm-color)
XTERM_TITLE='\[\033]0;\W@\u@\H\007\]'
;;
esac;
And since there you can use ${XTERM_TITLE} macro at begining of PS1 to set xterm title (if available) to directory@user@hostname. Or you can modify it (XTERM_TITLE=... line) using regular PS1 escape sequencies.
Positioning the Cursor
The folling 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.
List of colors for prompt and bash
Add this to your .bashrc to use colors in prompt and commands:
# misc NO_COLOR='\e[0m' #disable any colors # regular colors BLACK='\e[0;30m' RED='\e[0;31m' GREEN='\e[0;32m' YELLOW='\e[0;33m' BLUE='\e[0;34m' MAGENTA='\e[0;35m' CYAN='\e[0;36m' WHITE='\e[0;37m' # emphasized (bolded) colors EBLACK='\e[1;30m' ERED='\e[1;31m' EGREEN='\e[1;32m' EYELLOW='\e[1;33m' EBLUE='\e[1;34m' EMAGENTA='\e[1;35m' ECYAN='\e[1;36m' EWHITE='\e[1;37m' # underlined colors UBLACK='\e[4;30m' URED='\e[4;31m' UGREEN='\e[4;32m' UYELLOW='\e[4;33m' UBLUE='\e[4;34m' UMAGENTA='\e[4;35m' UCYAN='\e[4;36m' UWHITE='\e[4;37m' # background colors BBLACK='\e[40m' BRED='\e[41m' BGREEN='\e[42m' BYELLOW='\e[43m' BBLUE='\e[44m' BMAGENTA='\e[45m' BCYAN='\e[46m' BWHITE='\e[47m'
Use in commands (use curly brackets only if you need to specify text right after value $BLUE lol or ${BLUE}lol):
harvie@harvie-ntb ~ $ echo -e "${BLUE}lol"
lol
harvie@harvie-ntb ~ $ echo -e "${EBLUE}lol"
lol
harvie@harvie-ntb ~ $ echo -e "${UBLUE}lol"
lol
harvie@harvie-ntb ~ $ echo -e "${BBLUE}lol"
lol
Use in prompt (note double quotes and \[ \] used by bash to count prompt lenght in characters well):
PS1="\[$BLUE\]foo\[$RED\] bar\[$NO_COLOR\] baz : "
Return value visualisation
You can add this line to the end of your .bashrc if you want to see return value of last executed command. This should work with any kind of prompt as long as it don't need PROMPT_COMMAND.
PROMPT_COMMAND='RET=$?; if [[ $RET = 0 ]]; then echo -ne "\033[0;32m$RET\033[0m ;)"; else echo -ne "\033[0;31m$RET\033[0m ;("; fi; echo -n " "'
It will look like this:
0 ;) harvie@harvie-ntb ~/ $ true 0 ;) harvie@harvie-ntb ~/ $ false 1 ;( harvie@harvie-ntb ~/ $
Zero is green and non-zero is red. There is also smiley (you can replace it with anything what you want). So your bash will smile if last operation was succesful.
Better 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 this values in .bashrc:
#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;)'
Then you can use $RET_VALUE and $RET_SMILEY macros in PS1 (prompt). Note that you need use double quotes:
#prompt PS1="$RET_VALUE $RET_SMILEY : "
This will give you basic prompt :
0 ;) : true 0 ;) : false 1 ;( :
But you will probably want to use $RET_VALUE or $RET_SMILEY in your own prompt. like me:
PS1="\[$WHITE\]$RET_VALUE $RET_SMILEY \[$BLUE\]\u\[$RED\]@\[$EBLUE\]\h\[$WHITE\] \W \[$ERED\]\\$\[$EWHITE\] "
Advanced Prompts
Wolfman's
After reading through most of the Bash Prompt Howto, I 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 your home directory's .bashrc file.
- Comment out Arch's default prompt.
# PS1='[\u@\h \W]\$ '
- Next 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's section on 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
}
- This code generates the command prompt. There's not much to this. A bunch of 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
- If you want to play around with the colors of this prompt, open your
.bashrcfile in a text editor. When you want to see what the new prompt looks like, enter the following from your home directory, and the prompt will immediately change.
$ source ~/.bashrc