https://wiki.archlinux.org/api.php?action=feedcontributions&user=Bkerin&feedformat=atomArchWiki - User contributions [en]2024-03-29T06:45:14ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Bash/Prompt_customization&diff=95719Bash/Prompt customization2010-02-09T20:40:06Z<p>Bkerin: /* Return value visualisation */</p>
<hr />
<div>[[Category:Eye candy (English)]]<br />
[[Category:Command shells (English)]]<br />
[[Category:HOWTOs (English)]]<br />
{{i18n_links_start}}<br />
{{i18n_entry|English|Color_Bash_Prompt}}<br />
{{i18n_entry|Español|Colorear_Indicador_Bash (Español)}}<br />
{{i18n_entry|Italiano|Colorare_il_prompt_Bash_(Italiano)}}<br />
{{i18n_links_end}}<br />
<br />
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.<br />
<br />
==Basic prompts==<br />
The following settings are useful for distinguishing the root prompt from non-root users.<br />
<br />
*Edit Bash's personal configuration file:<br />
$ nano ~/.bashrc<br />
<br />
*Comment out the default prompt:<br />
#PS1='[\u@\h \W]\$ '<br />
<br />
*Add the following green prompt for regular users:<br />
export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '<br />
<br />
*Edit root's Bash file:<br />
# nano /root/.bash_profile<br />
<br />
*Assign a red prompt for root:<br />
export PS1='\[\e[1;31m\][\u@\h \W]\$\[\e[0m\] '<br />
<br />
==Advanced prompts==<br />
<br />
===List of colors for prompt and Bash===<br />
Add this to your Bash file(s) to define colors for prompt and commands:<br />
<pre>txtblk='\e[0;30m' # Black - Regular<br />
txtred='\e[0;31m' # Red<br />
txtgrn='\e[0;32m' # Green<br />
txtylw='\e[0;33m' # Yellow<br />
txtblu='\e[0;34m' # Blue<br />
txtpur='\e[0;35m' # Purple<br />
txtcyn='\e[0;36m' # Cyan<br />
txtwht='\e[0;37m' # White<br />
bldblk='\e[1;30m' # Black - Bold<br />
bldred='\e[1;31m' # Red<br />
bldgrn='\e[1;32m' # Green<br />
bldylw='\e[1;33m' # Yellow<br />
bldblu='\e[1;34m' # Blue<br />
bldpur='\e[1;35m' # Purple<br />
bldcyn='\e[1;36m' # Cyan<br />
bldwht='\e[1;37m' # White<br />
unkblk='\e[4;30m' # Black - Underline<br />
undred='\e[4;31m' # Red<br />
undgrn='\e[4;32m' # Green<br />
undylw='\e[4;33m' # Yellow<br />
undblu='\e[4;34m' # Blue<br />
undpur='\e[4;35m' # Purple<br />
undcyn='\e[4;36m' # Cyan<br />
undwht='\e[4;37m' # White<br />
bakblk='\e[40m' # Black - Background<br />
bakred='\e[41m' # Red<br />
badgrn='\e[42m' # Green<br />
bakylw='\e[43m' # Yellow<br />
bakblu='\e[44m' # Blue<br />
bakpur='\e[45m' # Purple<br />
bakcyn='\e[46m' # Cyan<br />
bakwht='\e[47m' # White<br />
txtrst='\e[0m' # Text Reset</pre><br />
<br />
To use in commands from your shell environment:<br />
$ echo -e "${txtblu}test"<br />
<font color='blue'>test</font><br />
$ echo -e "${bldblu}test"<br />
<font color='lightblue'><b>test</b></font><br />
$ echo -e "${undblu}test"<br />
<font color='lightblue'><b><u>test</u></b></font><br />
$ echo -e "${bakblu}test"<br />
<span style="color: white; background-color: lightblue"><b>test</b></span><br />
<br />
To use in a prompt (note double quotes and <nowiki>\[ \]</nowiki> used by the shell to count proper length):<br />
PS1="\[$txtblu\]foo\[$txtred\] bar\[$txtrst\] baz : "<br />
<br />
===Prompt escapes===<br />
The various Bash prompt escapes listed in the manpage:<br />
Bash allows these prompt strings to be customized by inserting a<br />
number of ''backslash-escaped special characters'' that are<br />
decoded as follows:<br />
<br />
\a an ASCII bell character (07)<br />
\d the date in "Weekday Month Date" format (e.g., "Tue May 26")<br />
\D{format} the format is passed to strftime(3) and the result<br />
is inserted into the prompt string an empty format<br />
results in a locale-specific time representation.<br />
The braces are required<br />
\e an ASCII escape character (033)<br />
\h the hostname up to the first `.'<br />
\H the hostname<br />
\j the number of jobs currently managed by the shell<br />
\l the basename of the shell's terminal device name<br />
\n newline<br />
\r carriage return<br />
\s the name of the shell, the basename of $0 (the portion following<br />
the final slash)<br />
\t the current time in 24-hour HH:MM:SS format<br />
\T the current time in 12-hour HH:MM:SS format<br />
\@ the current time in 12-hour am/pm format<br />
\A the current time in 24-hour HH:MM format<br />
\u the username of the current user<br />
\v the version of bash (e.g., 2.00)<br />
\V the release of bash, version + patch level (e.g., 2.00.0)<br />
\w the current working directory, with $HOME abbreviated with a tilde<br />
\W the basename of the current working directory, with $HOME<br />
abbreviated with a tilde<br />
\! the history number of this command<br />
\# the command number of this command<br />
\$ if the effective UID is 0, a #, otherwise a $<br />
\nnn the character corresponding to the octal number nnn<br />
\\ a backslash<br />
\[ begin a sequence of non-printing characters, which could be used<br />
to embed a terminal control sequence into the prompt<br />
\] end a sequence of non-printing characters<br />
<br />
The command number and the history number are usually different:<br />
the history number of a command is its position in the history<br />
list, which may include commands restored from the history file<br />
(see HISTORY below), while the command number is the position in<br />
the sequence of commands executed during the current shell session.<br />
After the string is decoded, it is expanded via parameter<br />
expansion, command substitution, arithmetic expansion, and quote<br />
removal, subject to the value of the promptvars shell option (see<br />
the description of the shopt command under SHELL BUILTIN COMMANDS<br />
below).<br />
<br />
===Positioning the cursor===<br />
The following sequence sets the cursor position:<br />
\[\033[<row>;<column>f\]<br />
<br />
The current cursor position can be saved using:<br />
\[\033[s\]<br />
<br />
To restore a position, use the following sequence: <br />
\[\033[u\]<br />
<br />
The following example uses these sequences to display the time in the upper right corner:<br />
PS1=">\[\033[s\]\[\033[1;\$((COLUMNS-4))f\]\$(date +%H:%M)\[\033[u\]"<br />
<br />
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.<br />
<br />
===Return value visualisation===<br />
<br />
WARNING WARNING WARNING WARNING<br><br />
This seemed to me to have some bugs, see the entry I added to the discussion page.<br />
<br />
Add this line if you want to see the return value of the last executed command. This should work with any kind of prompt as long as it does not need PROMPT_COMMAND:<br />
<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><br />
<br />
It will look like this:<br />
<font color="green">0</font><b> ;) </b>harvie@harvie-ntb ~/ $ true<br />
<font color="green">0</font><b> ;) </b>harvie@harvie-ntb ~/ $ false<br />
<font color="red">1</font><b> ;( </b>harvie@harvie-ntb ~/ $ <br />
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 succesful.<br />
<br />
====Advanced return value visualisation====<br />
If you want colors, you need to set ''$RED'' and ''$GREEN'' values:<br />
RED='\e[0;31m'<br />
GREEN='\e[0;32m'<br />
<br />
You have to specify these values in Bash's configuration files:<br />
<pre><br />
#return value visualisation<br />
PROMPT_COMMAND='RET=$?;'<br />
RET_VALUE='$(echo $RET)' #Ret value not colorized - you can modify it.<br />
RET_SMILEY='$(if [[ $RET=0 ]]; then echo -ne "\[$GREEN\];)"; else echo -ne "\[$RED\];("; fi;)'<br />
</pre><br />
<br />
Then you can use ''$RET_VALUE'' and ''$RET_SMILEY'' variables in the prompt. Note that you need use double quotes:<br />
#prompt<br />
PS1="$RET_VALUE $RET_SMILEY : "<br />
<br />
This will give you basic prompt:<br />
0 <font color="green">;)</font> : true<br />
0 <font color="green">;)</font> : false<br />
1 <font color="red">;(</font> : <br />
<br />
But you will probably want to use ''$RET_VALUE'' or ''$RET_SMILEY'' in your own prompt, like this:<br />
<pre><br />
PS1="\[$WHITE\]$RET_VALUE $RET_SMILEY \[$BLUE\]\u\[$RED\]@\[$EBLUE\]\h\[$WHITE\] \W \[$ERED\]\\$\[$EWHITE\] "<br />
</pre><br />
<br />
===Wolfman's===<br />
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 {{Filename|~/.bashrc}}.<br />
<br />
*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.<br />
##################################################<br />
# Fancy PWD display function<br />
##################################################<br />
# The home directory (HOME) is replaced with a ~<br />
# The last pwdmaxlen characters of the PWD are displayed<br />
# Leading partial directory names are striped off<br />
# /home/me/stuff -> ~/stuff if USER=me<br />
# /usr/share/big_dir_name -> ../share/big_dir_name if pwdmaxlen=20<br />
##################################################<br />
bash_prompt_command() {<br />
# How many characters of the $PWD should be kept<br />
local pwdmaxlen=25<br />
# Indicate that there has been dir truncation<br />
local trunc_symbol=".."<br />
local dir=${PWD##*/}<br />
pwdmaxlen=$(( ( pwdmaxlen < ${#dir} ) ? ${#dir} : pwdmaxlen ))<br />
NEW_PWD=${PWD/#$HOME/\~}<br />
local pwdoffset=$(( ${#NEW_PWD} - pwdmaxlen ))<br />
if [ ${pwdoffset} -gt "0" ]<br />
then<br />
NEW_PWD=${NEW_PWD:$pwdoffset:$pwdmaxlen}<br />
NEW_PWD=${trunc_symbol}/${NEW_PWD#*/}<br />
fi<br />
}<br />
<br />
*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.<br />
<br />
: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.<br />
bash_prompt() {<br />
case $TERM in<br />
xterm*|rxvt*)<br />
local TITLEBAR='\[\033]0;\u:${NEW_PWD}\007\]'<br />
;;<br />
*)<br />
local TITLEBAR=""<br />
;;<br />
esac<br />
local NONE="\[\033[0m\]" # unsets color to term's fg color<br />
<br />
# regular colors<br />
local K="\[\033[0;30m\]" # black<br />
local R="\[\033[0;31m\]" # red<br />
local G="\[\033[0;32m\]" # green<br />
local Y="\[\033[0;33m\]" # yellow<br />
local B="\[\033[0;34m\]" # blue<br />
local M="\[\033[0;35m\]" # magenta<br />
local C="\[\033[0;36m\]" # cyan<br />
local W="\[\033[0;37m\]" # white<br />
<br />
# emphasized (bolded) colors<br />
local EMK="\[\033[1;30m\]"<br />
local EMR="\[\033[1;31m\]"<br />
local EMG="\[\033[1;32m\]"<br />
local EMY="\[\033[1;33m\]"<br />
local EMB="\[\033[1;34m\]"<br />
local EMM="\[\033[1;35m\]"<br />
local EMC="\[\033[1;36m\]"<br />
local EMW="\[\033[1;37m\]"<br />
<br />
# background colors<br />
local BGK="\[\033[40m\]"<br />
local BGR="\[\033[41m\]"<br />
local BGG="\[\033[42m\]"<br />
local BGY="\[\033[43m\]"<br />
local BGB="\[\033[44m\]"<br />
local BGM="\[\033[45m\]"<br />
local BGC="\[\033[46m\]"<br />
local BGW="\[\033[47m\]"<br />
<br />
local UC=$W # user's color<br />
[ $UID -eq "0" ] && UC=$R # root's color<br />
<br />
PS1="$TITLEBAR ${EMK}[${UC}\u${EMK}@${UC}\h ${EMB}\${NEW_PWD}${EMK}]${UC}\\$ ${NONE}"<br />
# without colors: PS1="[\u@\h \${NEW_PWD}]\\$ "<br />
# extra backslash in front of \$ to make bash colorize the prompt<br />
}<br />
<br />
*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.<br />
PROMPT_COMMAND=bash_prompt_command<br />
bash_prompt<br />
unset bash_prompt<br />
<br />
==Set xterm window title==<br />
You can use the {{Codeline|<nowiki>${XTERM_TITLE}</nowiki>}} variable at the beginning of the prompt to set [[xterm]] title (if available) to directory@user@hostname. Or you can modify it using regular [[#Prompt escapes|prompt escape sequences]]:<br />
<pre><br />
#set xterm title<br />
case "$TERM" in<br />
xterm | xterm-color)<br />
XTERM_TITLE='\[\033]0;\W@\u@\H\007\]'<br />
;;<br />
esac;<br />
</pre><br />
<br />
==External links==<br />
* Forum Discussions:<br />
** [http://bbs.archlinux.org/viewtopic.php?id=1817 BASH prompt]<br />
** [http://bbs.archlinux.org/viewtopic.php?id=50885 What's your PS1?]<br />
* http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html<br />
* http://www.shelluser.net/~giles/bashprompt/prompts/index.html</div>Bkerinhttps://wiki.archlinux.org/index.php?title=Talk:Bash/Prompt_customization&diff=95718Talk:Bash/Prompt customization2010-02-09T20:36:22Z<p>Bkerin: fixing the bugs in the return value visualization</p>
<hr />
<div>The return value visualization stuff didn't quite work right for me.<br />
The command history prints out funny (bits of old command prefixes<br />
stay displayed), and also long lines behaved oddly (wrapped back to<br />
start etc.).<br />
<br />
I think the trouble maybe coming from echo'ing out color commands<br />
with one echo then putting out the characters to reset the font<br />
elsewhere. I asked on the bash list and ended up doing this:<br />
<br />
# Make the prompt dark red when the previous command has succeeded, or<br />
# bright green when it has failed (in keeping with the slightly backwards<br />
# way exit codes work :).<br />
red=$(tput setaf 1)<br />
bright_green=$(tput bold; tput setaf 2)<br />
reset=$(tput sgr0)<br />
# Namespace'ed last user command exit status. We need this I think because<br />
# the tput commands in the subshells end up resetting $?.<br />
PROMPT_COMMAND='MYPROMPT_LUCES=$?' <br />
colors=("$red" "$bright_green")<br />
PS1='\[${colors[$? != 0]}\]$(if [ $MYPROMPT_LUCES != 0 ]; then \<br />
echo "$MYPROMPT_LUCES "; \<br />
fi)\$\[$reset\] '<br />
<br />
which displays prompts following successful commands in dark red, and prompts<br />
following failing commands in bright green with the exit code shown.</div>Bkerin