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 own strftime 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 to fi. Also remove the ${BRANCH} from the last line of the prompt_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.

TerminalPromptFullMonty

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
}