Advanced Bash Prompt Customization: Practical Examples for Developers


6 views

As a developer working extensively in terminal environments, I've found that a well-crafted shell prompt can significantly boost productivity. The default Bash prompt often lacks crucial information and doesn't leverage terminal capabilities effectively.

Here are key elements I recommend including in professional prompts:

# Current directory (truncated if too long)
# Git/svn/hg status when in version-controlled directories
# Exit status of last command
# Timestamp of command execution
# Hostname when in SSH sessions
# User/privilege indication

Here's my current production-grade prompt configuration:

# In .bashrc or .bash_profile
export PS1='$$\033[01;32m$$\u@\h$$\033[00m$$:$$\033[01;34m$$\w$$\033[00m$$$(__git_ps1 " (%s)") \$ '

For more visual feedback:

PS1='$$\e[1;33m$$\t $$\e[1;32m$$\u@\h $$\e[1;34m$$\w $$\e[1;35m$$$(__git_ps1 "(%s)") $$\e[1;31m$$\$ $$\e[0m$$'

For tracking command execution time:

function timer_start {
  timer=${timer:-$SECONDS}
}

function timer_stop {
  timer_show=$(($SECONDS - $timer))
  unset timer
}

trap 'timer_start' DEBUG
PROMPT_COMMAND=timer_stop

PS1='[${timer_show}s] \w\$ '

For comprehensive Git status:

GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWUPSTREAM="auto"
PS1='\u@\h \w$(__git_ps1 " (%s)") \$ '

Always escape non-printing characters properly to avoid line wrapping issues:

# Correct:
PS1='$$\033[01;32m$$\u@\h$$\033[00m$$:$$\033[01;34m$$\w$$\033[00m$$\$ '

# Incorrect (will cause display issues):
PS1='\033[01;32m\u@\h\033[00m:\033[01;34m\w\033[00m\$ '

For zsh users:

autoload -Uz vcs_info
precmd() { vcs_info }
zstyle ':vcs_info:*' formats ' (%s)-[%b]'
setopt PROMPT_SUBST
PROMPT='%n@%m %~${vcs_info_msg_0_} %# '

As developers, we spend countless hours in terminal sessions. A well-configured prompt isn't just about aesthetics - it provides crucial context about your environment, command history, and system status. Let's explore some powerful prompt customizations that go beyond basic color changes.

First, understand these key Bash special characters:


\u - username
\h - hostname
\w - current working directory
\n - newline
\e - escape character
\033 - octal escape sequence

Building on the history example from the question, here's an enhanced version that includes the command number:


PS1='$$\e[32m$$\u@\h $$\e[33m$$\w $$\e[36m$$[\#]\n$$\e[0m$$\$ '
trap 'echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD} - $(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")\007"' DEBUG

This shows username, host, directory, command number, and updates the window title with the current command.

For developers working with Git:


parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* $.*$/ (\1)/'
}
PS1='$$\033[01;32m$$\u@\h$$\033[00m$$:$$\033[01;34m$$\w$$\033[01;31m$$$(parse_git_branch)$$\033[00m$$\$ '

This displays the current Git branch in red when you're in a repository.

A comprehensive prompt with multiple information lines:


PS1='\n$$\e[1;37m$$[$$\e[1;32m$$\u$$\e[0;37m$$@$$\e[1;35m$$\h$$\e[1;37m$$] $$\e[1;33m$$\w $$\e[1;36m$$$(date +%H:%M)\n$$\e[1;31m$$\$ $$\e[0m$$'

Features include: time display, clear separation between commands, and distinct colors for different elements.

For mobile developers:


battery_status() {
    if [[ $(uname) == "Darwin" ]]; then
        pmset -g batt | grep -o "[0-9]*%"
    else
        cat /sys/class/power_supply/BAT*/capacity
    fi
}
PS1='$$\e[32m$$\u@\h $$\e[33m$$\w $$\e[31m$$$(battery_status)$$\e[0m$$\$ '

Show whether the previous command succeeded or failed:


PS1='${debian_chroot:+($debian_chroot)}$$\033[01;32m$$\u@\h$$\033[00m$$:$$\033[01;34m$$\w$$\033[00m$$$(if [ $? -eq 0 ]; then echo "$$\033[01;32m$$ ✔"; else echo "$$\033[01;31m$$ ✘"; fi)\$ '

Add these to your ~/.bashrc or appropriate shell configuration file. For immediate effect after editing, run:


source ~/.bashrc

Remember to test your prompt with different terminal emulators as some escape sequences may behave differently.