Customize BASH Prompt¶
Customize the BASH (GNU Bourne-Again SHell) shell prompt that is visible in the shell or terminal.
Simple Prompt¶
Features¶
Prompt features are broken down in order as they appear.
- Username of the currently logged in user.
- Hostname of the connected system.
- tty (teletype)/pts (psuedo terminal slave) session number on the connected system. TTY, physically at the console. PTS, SSH session.
- Date and time of the connected system.
- Current working directory.
- Total files within the current working directory.
- Total consumed space of the files within the current working directory.
Prompt Preview¶
Installation¶
- Create "/etc/bash.bashrc" file.
$ sudo nano /etc/bash.bashrc
# set a fancy prompt (non-color, overwrite the one in /etc/profile) #PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' clientConnType=$(tty) clientConnType=`echo "$clientConnType" | sed -r 's/\/dev\///g'` PS1="\n\[\e[30;1m\]\[\016\]-\[\017\]($(if [[ ${EUID} == 0 ]]; then echo '\[\033[01;31m\]\u'; else echo '\[\e[34;1m\]\u';fi)\[\e[0;36m\]@\[\e[34;1m\]\h\[\e[30;1m\])-(\[\e[34;1m\]$clientConnType\[\e[30;1m\])-(\[\e[34;1m\]\D{%F} \t\[\e[30;1m\])\[\e[30;1m\]\[\016\]\[\017\]-(\[\[\e[32;1m\]\w\[\e[30;1m\])-(\[\e[00;31m\]\$(/bin/ls -1 | /usr/bin/wc -l | /bin/sed 's: ::g') files, \$(/bin/ls -lah | /bin/grep -m 1 total | /bin/sed 's/total //')b\[\e[30;1m\])\n-> \[\e[0m\]"
- For changes to take affect restart the session.
Contextual Prompt¶
Features¶
Prompt features are broken down in order as they appear.
1st Line: - Date and time on the connected system. - Command history line number. - Session command number. - Connection type, tty (teletype)/pts (psuedo terminal slave) and session number on the connected system. TTY, physically at the console. PTS, SSH session.
2nd Line: - Username of the currently logged in user (blue=regular user, red=root user). - Hostname of the connected system. - Total files within the current working directory. * Current working directory.
3nd Line (contextual these features will appear): - GIT branch name. - GIT branch status (detached, untracked files, commit needed, branch is ahead of upstream and branch is behind of upstream).
4th Line: - The "$" represents a regular user is in use. - The "$" represents a elevated user is in use. - The color green of "$" and "#" represents success of the last command. - The color red of "$" and "#" represents failure of the last command.
Prompt Preview¶
Installation¶
- Add the following to the bottom of the file "/etc/bash.bashrc".
# nano /etc/bash.bashrc
# source our aliases, and environment files if [ -f /etc/bash.d/environment ]; then source /etc/bash.d/environment; fi if [ -f /etc/bash.d/aliases ]; then source /etc/bash.d/aliases; fi # if running X-based Terminal in a local X session if [ !-x ${DISPLAY} ]; then 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 fi # source bash completion if user can read /usr/share/bash-completion/bash_completion [ -r /usr/share/bash-completion/bash_completion ] && . /usr/share/bash-completion/bash_completion
- Create a new directory "/etc/bash.d".
$ sudo mkdir /etc/bash.d
- Add global system aliases.
# nano /etc/bash.d/aliases
# if /usr/bin/dircolors exists & we can execute it if [ -x /usr/bin/dircolors ]; then test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" alias ls='ls --color=auto' alias tree='tree -C' alias dir='dir --color=auto' alias grep='grep --color=auto' alias dmesg='dmesg -T --color' #-T makes human readable timestamps fi alias ll='ls -al' alias la='ls -A' alias l='ls -CF'
- Create the environment file.
# nano /etc/bash.d/environment
#load the functions file, return if is not present if [ -f "/etc/bash.d/functions" ]; then source /etc/bash.d/functions; else echo "Functions file missing in /etc/bash.d"; return; fi export PROMPT_COMMAND=prompt_generator; export EDITOR="/usr/bin/nano";
- Create the functions file.
# nano /etc/bash.d/functions
#copied verbatim from OSX El Capitan /etc/bash_bashrc_Apple_Terminal update_terminal_cwd () { local url_path=''; { local i ch hexch LC_CTYPE=C LC_ALL=; for ((i = 0; i < ${#PWD}; ++i)) do ch="${PWD:i:1}"; if [[ "$ch" =~ [/._~A-Za-z0-9-] ]]; then url_path+="$ch"; else printf -v hexch "%02X" "'$ch"; url_path+="%${hexch: -2:2}"; fi; done }; printf '\e]7;%s\a' "file://$HOSTNAME$url_path" } function prompt_generator() { local EXIT=$?; #get last command exit status before doing anything else #this is done to force PS1 to a newline if the cursor ended up somewhere other than the last margin PS1='$(printf "%$((COLUMNS-1))s\r")'; # Reset local Color_Off='\[\e[0m\]'; # Text Reset # ASCII Foreground Colors Bold High Intensity Bold High Intensity local Red='\[\e[0;31m\]'; local BRed='\[\e[1;31m\]'; local IRed='\[\e[0;91m\]'; local BIRed='\[\e[1;91m\]'; local Green='\[\e[0;32m\]'; local BGreen='\[\e[1;32m\]'; local IGreen='\[\e[0;92m\]'; local BIGreen='\[\e[1;92m\]'; local Yellow='\[\e[0;33m\]'; local BYellow='\[\e[1;33m\]'; local IYellow='\[\e[0;93m\]'; local BIYellow='\[\e[1;93m\]'; local Blue='\[\e[0;34m\]'; local BBlue='\[\e[1;34m\]'; local IBlue='\[\e[0;94m\]'; local BIBlue='\[\e[1;94m\]'; local Purple='\[\e[0;35m\]'; local BPurple='\[\e[1;35m\]'; local IPurple='\[\e[0;95m\]'; local BIPurple='\[\e[1;95m\]'; local Cyan='\[\e[0;36m\]'; local BCyan='\[\e[1;36m\]'; local ICyan='\[\e[0;96m\]'; local BICyan='\[\e[1;96m\]'; local White='\[\e[0;37m\]'; local BWhite='\[\e[1;37m\]'; local IWhite='\[\e[0;97m\]'; local BIWhite='\[\e[1;97m\]'; local Gray='\[\e[0;90m\]'; local LightGray='\[\e[0;30m\]'; # ASCII High Intensity Background Colors local On_IBlack='\[\e[0;100m\]'; # Black local On_IRed='\[\e[0;101m\]'; # Red local On_IGreen='\[\e[0;102m\]'; # Green local On_IYellow='\[\e[0;103m\]'; # Yellow local On_IBlue='\[\e[0;104m\]'; # Blue local On_IPurple='\[\e[0;105m\]'; # Purple local On_ICyan='\[\e[0;106m\]'; # Cyan local On_IWhite='\[\e[0;107m\]'; # White #256 Foreground Colors local Orange='\[\e[38;5;209m\]'; # Glyphs http://www.utf8-chartable.de/unicode-utf8-table.pl?start=9472&number=1024 local Checkmark="${BIGreen}$( echo -e "\xE2\x9C\x93" )${Color_Off}"; local Xmark="${BIRed}$( echo -e "\xE2\x9C\x95" )${Color_Off}"; local Lines_Color=$White; local Light_Down_Right="${Lines_Color}$(echo -e "\xE2\x94\x8C")${Color_Off}"; local Light_Vert_Right="${Lines_Color}$(echo -e "\xE2\x94\x9C")${Color_Off}"; local Light_Up_Right="${Lines_Color}$(echo -e "\xE2\x94\x94")${Color_Off}"; local Left_Square="${Lines_Color}$( echo -e "\xE2\x9F\xA6" )"; local Right_Square="$( echo -e "\xE2\x9F\xA7" )${Color_Off}"; local Line="${Lines_Color}$(echo -e "\xE2\x94\x80" )${Color_Off}"; local Start_Parenthesis="${Lines_Color}(${Color_Off}"; local End_Parenthesis="${Lines_Color})${Color_Off}"; local Exit_Status_Color=$BIGreen if [ $EXIT != 0 ]; then Exit_Status_Color=$BIRed; fi local PROMPT="${Exit_Status_Color}\$ ${Color_Off}"; local UsernameColor="${BIBlue}"; #turn username red if root if [ $EUID == 0 ]; then UsernameColor="${BIRed}"; PROMPT="${Exit_Status_Color}# ${NarrowSpace}${Color_Off}"; fi #command separator PS1+="${Gray}"; let Fillsize=${COLUMNS}-60; while [ $Fillsize -gt 0 ] do PS1+='-'; let Fillsize-=1; done #timestamp PS1+="${Left_Square}\D{%Y-%m-%d} \t${Right_Square}"; #command history line number PS1+="${Line}${Left_Square}History: \!${Right_Square}"; #session command number PS1+="${Line}${Left_Square}Session: \#${Right_Square}" #TTY PS1+="${Line}${Left_Square}$(tty | awk 'BEGIN { FS = "/" } ; {print $3"/"$4}')${Right_Square}"; #should be one char left to fill PS1+="${Gray}-${Color_Off}"; #username@FQD_hostname PS1+="\n${Light_Down_Right}${UsernameColor}\u${Color_Off}"; PS1+="${Lines_Color}@${Color_Off}"; PS1+="${BIGreen}\H${Color_Off}"; #pwd PS1+="${Line}${Start_Parenthesis}$( ls -a | wc -l | awk '{print $1 " files"}' )${End_Parenthesis}"; PS1+="${Line}${Start_Parenthesis}\w${End_Parenthesis}"; #if we are in a directory that contains a .git folder, do magic! local Git_Branch; if Git_Branch=$(git rev-parse --abbrev-ref HEAD 2> /dev/null); then PS1+="\n${Light_Vert_Right}${Start_Parenthesis}GIT Branch: "; if [ $Git_Branch == 'HEAD' ]; then PS1+="detached*"; else PS1+="$Git_Branch"; fi PS1+="${End_Parenthesis}"; local Short_Status_Array=( $(git status --porcelain 2> /dev/null) ); local Commit_Needed=false; local Long_Status_Array=$(git status 2> /dev/null); if [[ "${Short_Status_Array[@]}" =~ "??" ]]; then PS1+="${Line}${Start_Parenthesis}${Red}Untracked files present!${Color_Off}${End_Parenthesis}"; fi if [[ "${Short_Status_Array[@]}" =~ [MADRCU] ]]; then PS1+="${Line}${Start_Parenthesis}${Orange}Commit Needed!${Color_Off}${End_Parenthesis}"; fi if [ $Commit_Needed == false ]; then if [[ ${Long_Status_Array[@]} =~ 'Your branch is ahead of' ]]; then PS1+="${Line}${Start_Parenthesis}${Cyan}Push needed.${Color_Off}${End_Parenthesis}"; elif [[ ${Long_Status_Array[@]} =~ 'Your branch is behind' ]]; then PS1+="${Line}${Start_Parenthesis}${BIRed}Behind upstream! 'git pull --rebase' required!${Color_Off}${End_Parenthesis}"; fi fi fi #prompts PS1+="\n${PROMPT}"; update_terminal_cwd; }
- For changes to take affect restart the session.