My new favorite Bash prompt
I do a lot in Terminal. Sometimes, it’s easier. Sometimes it’s faster. Sometimes I’d just rather type it out. Whatever the reason, I’ve never been able to stand looking at a boring shell prompt. Bash is my primary shell, mostly because I’ve never taken the time to learn much else. I’ll get there someday. For now, here’s my current Bash shell prompt…
I’m using the PROMPT_COMMAND
variable to run a few quick functions to generate the prompt. It doesn’t do anything processor-intensive, so I haven’t seen any lag caused by this one (unlike some of my previous experiments). PROMPT_COMMAND
is set to call a function called, appropriately, prompt_command()
. This, in turn, calls a few external functions defined in my .bash_profile
. To use it, just stick all of the code below into your .bash_profile
, and modify it as you see fit. Be sure to replace any definitions of PROMPT_COMMAND
or PS1
.
The prompt has a few unique features, and some “hidden” features:
- The current time is formatted just the way I like it. You can modify the
fmt_time
function with your ownstrftime
strings as desired. - The current 1m average CPU load is included in the prompt in dark grey, gathered using a quick
uptime
command. - If the previous command returned an error message, the error code returned will show up at the end of the first line in red.
- If you use Git, and your current working directory is a Git repository, the current branch will be shown in green before the actual prompt on the second line. This might cause problems if you don’t have Git installed; if you see Git-related errors, you can remove the section of the code under the Git comment from
if
tofi
. Also remove the${BRANCH}
from the last line of theprompt_command
function. - Lastly, it sets the title of the tab in Terminal to the last two portions of the current working directory (
pwd
) string, meaning the current directory and its parent directory.
All of the colors used in the prompt are defined as shell variables. In the final line of the prompt_command
function, you can modify the colors just by replacing the color names in the line. That should be pretty self-explanatory.
prompt_command () {
if [ $? -eq 0 ]; then # set an error string for the prompt, if applicable
ERRPROMPT=" "
else
ERRPROMPT='->($?) '
fi
if [ "\$(type -t __git_ps1)" ]; then # if we're in a Git repo, show current branch
BRANCH="\$(__git_ps1 '[ %s ] ')"
fi
local TIME=`fmt_time` # format time for prompt string
local LOAD=`uptime|awk '{min=NF-2;print $min}'`
local GREEN="\[\033[0;32m\]"
local CYAN="\[\033[0;36m\]"
local BCYAN="\[\033[1;36m\]"
local BLUE="\[\033[0;34m\]"
local GRAY="\[\033[0;37m\]"
local DKGRAY="\[\033[1;30m\]"
local WHITE="\[\033[1;37m\]"
local RED="\[\033[0;31m\]"
# return color to Terminal setting for text color
local DEFAULT="\[\033[0;39m\]"
# set the titlebar to the last 2 fields of pwd
local TITLEBAR='\[\e]2;`pwdtail`\a'
export PS1="\[${TITLEBAR}\]${CYAN}[ ${BCYAN}\u${GREEN}@${BCYAN}\
\h${DKGRAY}(${LOAD}) ${WHITE}${TIME} ${CYAN}]${RED}$ERRPROMPT${GRAY}\
\w\n${GREEN}${BRANCH}${DEFAULT}$ "
}
PROMPT_COMMAND=prompt_command
fmt_time () { #format time just the way I likes it
if [ `date +%p` = "PM" ]; then
meridiem="pm"
else
meridiem="am"
fi
date +"%l:%M:%S$meridiem"|sed 's/ //g'
}
pwdtail () { #returns the last 2 fields of the working directory
pwd|awk -F/ '{nlast = NF -1;print $nlast"/"$NF}'
}
chkload () { #gets the current 1m avg CPU load
local CURRLOAD=`uptime|awk '{print $8}'`
if [ "$CURRLOAD" > "1" ]; then
local OUTP="HIGH"
elif [ "$CURRLOAD" < "1" ]; then
local OUTP="NORMAL"
else
local OUTP="UNKNOWN"
fi
echo $CURRLOAD
}