Prompt Customization¶
The prompt is what you see before typing commands. Customizing it can improve your workflow by showing useful information at a glance.
Prompt Variables¶
| Variable | Purpose |
|---|---|
PS1 | Primary prompt (what you see) |
PS2 | Continuation prompt (after \) |
PS3 | Select menu prompt |
PS4 | Debug trace prefix |
Basic PS1¶
Default prompts look like:
Set a custom prompt:
Escape Sequences¶
Special sequences expand to information:
| Sequence | Meaning |
|---|---|
\u | Username |
\h | Hostname (short) |
\H | Hostname (full) |
\w | Working directory (full) |
\W | Working directory (basename) |
\d | Date (Tue May 26) |
\t | Time (24h HH:MM:SS) |
\T | Time (12h HH:MM:SS) |
\@ | Time (12h am/pm) |
\A | Time (24h HH:MM) |
\n | Newline |
\r | Carriage return |
\\ | Literal backslash |
\$ | $ for user, # for root |
\[ | Start non-printing sequence |
\] | End non-printing sequence |
\! | History number |
\# | Command number |
\j | Number of background jobs |
Color Codes¶
ANSI Colors¶
Wrap colors in \[ and \] so bash knows they don't take space:
# Format: \[\e[CODEm\]
# Reset: \[\e[0m\]
RED='\[\e[31m\]'
GREEN='\[\e[32m\]'
YELLOW='\[\e[33m\]'
BLUE='\[\e[34m\]'
MAGENTA='\[\e[35m\]'
CYAN='\[\e[36m\]'
WHITE='\[\e[37m\]'
RESET='\[\e[0m\]'
PS1="${GREEN}\u${RESET}@${BLUE}\h${RESET}:${YELLOW}\w${RESET}\$ "
Extended Colors¶
256 colors and bold/dim:
# Bold
BOLD='\[\e[1m\]'
# 256 colors: \[\e[38;5;COLORm\]
ORANGE='\[\e[38;5;208m\]'
PURPLE='\[\e[38;5;141m\]'
PS1="${BOLD}${ORANGE}\u${RESET}:${PURPLE}\w${RESET}\$ "
Practical Prompt Examples¶
Minimal¶
Classic¶
Colorful¶
Two-Line¶
With Time¶
With Exit Code¶
PS1='$(if [ $? -eq 0 ]; then echo "\[\e[32m\]o\[\e[0m\]"; else echo "\[\e[31m\]x\[\e[0m\]"; fi) \w\$ '
Shows green o for success, red x for failure.
Dynamic Prompts¶
Using PROMPT_COMMAND¶
PROMPT_COMMAND runs before each prompt:
Or use it to update PS1:
set_prompt() {
local exit_code=$?
local red='\[\e[31m\]'
local green='\[\e[32m\]'
local reset='\[\e[0m\]'
if [[ $exit_code -eq 0 ]]; then
PS1="${green}>${reset} "
else
PS1="${red}>${reset} "
fi
}
PROMPT_COMMAND=set_prompt
Git Branch in Prompt¶
Show current git branch:
parse_git_branch() {
git branch 2>/dev/null | grep '^*' | sed 's/* //'
}
PS1='\w $(parse_git_branch)\$ '
With color and formatting:
parse_git_branch() {
local branch
branch=$(git branch 2>/dev/null | grep '^*' | sed 's/* //')
[[ -n "$branch" ]] && echo "($branch) "
}
PS1='\[\e[34m\]\w\[\e[0m\] \[\e[33m\]$(parse_git_branch)\[\e[0m\]\$ '
Git Status Indicator¶
git_prompt() {
local branch
branch=$(git branch 2>/dev/null | grep '^*' | sed 's/* //')
[[ -z "$branch" ]] && return
local status=""
git diff --quiet 2>/dev/null || status="*"
git diff --cached --quiet 2>/dev/null || status="${status}+"
echo "($branch$status) "
}
PS1='\w $(git_prompt)\$ '
Shows * for unstaged changes, + for staged changes.
Starship Prompt¶
Starship is a modern, cross-shell prompt that's highly recommended:
Install¶
Enable¶
Add to end of ~/.bashrc:
Configure¶
Create ~/.config/starship.toml:
# Minimal config
format = """
$directory$git_branch$git_status$character"""
[character]
success_symbol = "[>](bold green)"
error_symbol = "[>](bold red)"
[directory]
truncation_length = 3
truncate_to_repo = true
[git_branch]
format = "[$branch]($style) "
style = "bold yellow"
[git_status]
format = '([$all_status$ahead_behind]($style) )'
Starship Advantages¶
- Cross-shell (bash, zsh, fish, PowerShell)
- Fast (written in Rust)
- Extensive customization
- Built-in git, language version, cloud context support
- Active development
Common Prompt Configurations¶
Developer Prompt¶
# Shows: user, directory, git, virtualenv
dev_prompt() {
local git_branch
git_branch=$(git branch 2>/dev/null | grep '^*' | sed 's/* //')
local venv=""
[[ -n "$VIRTUAL_ENV" ]] && venv="($(basename $VIRTUAL_ENV)) "
PS1="${venv}\[\e[32m\]\u\[\e[0m\]:\[\e[34m\]\w\[\e[0m\]"
[[ -n "$git_branch" ]] && PS1+=" \[\e[33m\]($git_branch)\[\e[0m\]"
PS1+="\$ "
}
PROMPT_COMMAND=dev_prompt
Server Prompt¶
Highlight root and show hostname:
if [[ $EUID -eq 0 ]]; then
PS1='\[\e[31m\]\u@\h\[\e[0m\]:\w# '
else
PS1='\[\e[32m\]\u\[\e[0m\]@\h:\w\$ '
fi
Minimal Fast Prompt¶
Keep it simple for speed:
PS2, PS3, PS4¶
PS2 - Continuation¶
When command continues to next line:
PS3 - Select Menu¶
Used by select command:
PS3="Choose an option: "
select opt in "One" "Two" "Quit"; do
echo "You chose: $opt"
[[ $opt == "Quit" ]] && break
done
PS4 - Debug Trace¶
Prefix for set -x output:
Troubleshooting¶
Prompt Wraps Incorrectly¶
Non-printing characters must be wrapped:
Prompt is Slow¶
Git operations can slow prompts. Cache or simplify:
Or use Starship which is optimized for speed.
Colors Don't Work¶
Check terminal supports colors:
Try It¶
-
Basic customization:
-
Add colors:
-
Add git branch:
-
Try Starship:
Summary¶
| Variable | Purpose |
|---|---|
PS1 | Main prompt |
PS2 | Continuation prompt |
PS3 | Select menu prompt |
PS4 | Debug trace prefix |
PROMPT_COMMAND | Run before each prompt |
Key escape sequences:
| Sequence | Meaning |
|---|---|
\u | Username |
\h | Hostname |
\w | Full path |
\W | Current directory |
\$ | $ or # |
\[...\] | Non-printing (colors) |
For most users, Starship is recommended for a modern, fast, customizable prompt.