- Posted on
- • Artificial Intelligence
Prompt Templates for Bash
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Prompt Templates for Bash: Turn Your Shell Into a Heads‑Up Display
If your command line only shows “user@host:~$”, you’re leaving productivity on the table. A well-designed Bash prompt can surface the information you need—current directory, Git status, Python virtualenv, exit codes, command duration—exactly when you need it. That means fewer mistakes, less context-switching, and faster workflows.
This article explains how to think about prompt “templates,” why they’re worth your time, and gives you practical examples you can paste into your shell today. We’ll start with pure Bash, then show popular prompt frameworks you can install via apt, dnf, and zypper.
Why prompt templates matter
Reduce mental overhead: See project, branch, and environment at a glance.
Prevent mistakes: Make production hosts or root shells visually loud; catch failures instantly.
Navigate faster: Shorten the cycle of typing, running, and verifying with immediate context.
Portable wins: A good prompt works across TTYs, multiplexers (tmux/screen), and remote SSH sessions.
What we’ll build
1) A reliable, minimal Bash prompt template with color, status, and a newline.
2) Git-aware prompts using the built-in __git_ps1.
3) Starship: a fast, cross-shell, batteries-included prompt.
4) Powerline: classic segmented prompts with patched fonts.
5) Context-aware prompts per host/project (optional, with direnv).
1) Build a robust Bash prompt template
The core idea: compute dynamic parts in a function and assign PS1. Use \[ \] around non-printing sequences so line editing remains accurate.
Add this to your ~/.bashrc:
# 1) Safe color helpers (tput if available, ANSI fallback)
if tput setaf 1 &>/dev/null; then
reset="$(tput sgr0)"; bold="$(tput bold)"
red="$(tput setaf 1)"; green="$(tput setaf 2)"; yellow="$(tput setaf 3)"
blue="$(tput setaf 4)"; magenta="$(tput setaf 5)"; cyan="$(tput setaf 6)"
else
reset='\e[0m'; bold='\e[1m'
red='\e[31m'; green='\e[32m'; yellow='\e[33m'
blue='\e[34m'; magenta='\e[35m'; cyan='\e[36m'
fi
# 2) Core prompt function
set_bash_prompt() {
local exit=$? # exit status of last command
local jobs_count="$(jobs -p | wc -l | tr -d ' ')" # background jobs
local venv=""
[ -n "$VIRTUAL_ENV" ] && venv="(\$(basename \"$VIRTUAL_ENV\")) "
# Optional SSH/ROOT cues
local hostpart="\u@\h"
[ -n "$SSH_TTY" ] && hostpart="ssh:${hostpart}"
[ "$EUID" -eq 0 ] && hostpart="ROOT:${hostpart}"
# Status segment: exit code and background jobs
local status=""
[ "$exit" -ne 0 ] && status="\[${red}\]✗$exit\[${reset}\] "
[ "$jobs_count" -gt 0 ] && status="${status}\[${yellow}\]⚙${jobs_count}\[${reset}\] "
# Compose: status user@host cwd (and leave room for git later)
PS1="${status}\[${cyan}${bold}\]${hostpart}\[${reset}\] "\
"\[${blue}\]\w\[${reset}\] ${venv}\n\$ "
}
PROMPT_COMMAND=set_bash_prompt
Reload your shell:
source ~/.bashrc
You now have:
Colorized user@host and current directory.
Exit code when commands fail.
Background job count.
A clean newline before the
$prompt.
Tip: Put long or heavy computations (like scanning directories) behind conditions or leave them to specialized helpers to keep the prompt snappy.
2) Make it Git-aware with __git_ps1 (no heavy frameworks required)
Bash ships with a handy __git_ps1 function (from Git’s completion/prompt scripts). It’s fast and configurable.
Install Git if you don’t have it:
Debian/Ubuntu (apt):
sudo apt update && sudo apt install -y gitFedora/RHEL (dnf):
sudo dnf install -y gitopenSUSE (zypper):
sudo zypper install -y git
Enable the git prompt helper in ~/.bashrc (path varies by distro, so try in order):
# Load __git_ps1 from wherever your distro ships it
for p in \
/usr/share/git/completion/git-prompt.sh \
/usr/share/git-core/contrib/completion/git-prompt.sh \
/etc/bash_completion.d/git-prompt \
; do
[ -r "$p" ] && source "$p" && break
done
# Make __git_ps1 show more detail
export GIT_PS1_SHOWDIRTYSTATE=1 # * changes, + staged
export GIT_PS1_SHOWSTASHSTATE=1 # $ stash
export GIT_PS1_SHOWUNTRACKEDFILES=1 # % untracked
export GIT_PS1_SHOWUPSTREAM=auto # <, > ahead/behind
Now, add the branch segment to your prompt. Adjust the PS1 line inside set_bash_prompt() like this:
PS1="${status}\[${cyan}${bold}\]${hostpart}\[${reset}\] "\
"\[${blue}\]\w\[${reset}\]$(__git_ps1 ' [%s]') ${venv}\n\$ "
Reload:
source ~/.bashrc
Result: Whenever you’re in a Git repo, your prompt shows the branch plus status marks—without running slow Git commands in your own code.
Optional: Prefer a full-featured theme? You can use bash-git-prompt instead:
apt:
sudo apt install -y bash-git-promptdnf:
sudo dnf install -y bash-git-promptzypper:
sudo zypper install -y bash-git-prompt
Then in ~/.bashrc:
GIT_PROMPT_ONLY_IN_REPO=1
source /usr/share/bash-git-prompt/gitprompt.sh
If your repo doesn’t have a package, clone it:
git clone https://github.com/magicmonty/bash-git-prompt.git ~/.bash-git-prompt --depth 1
source ~/.bash-git-prompt/gitprompt.sh
3) Starship: a fast, cross‑shell prompt with smart defaults
Starship auto-detects tools (Git, Node, Python, Docker, Kubernetes, etc.) and shows just enough info, quickly.
Install Starship:
apt:
sudo apt update && sudo apt install -y starship- If not found:
curl -fsSL https://starship.rs/install.sh | sh
- If not found:
dnf:
sudo dnf install -y starshipzypper:
sudo zypper install -y starship
Enable for Bash (in ~/.bashrc):
eval "$(starship init bash)"
Customize with ~/.config/starship.toml:
# Show status, path, git, and duration; put prompt on two lines
format = "$status$directory$git_branch$git_state$git_status$cmd_duration\n$character"
[status]
disabled = false
style = "bold red"
format = "[$symbol$common_meaning$signal_name]($style) "
[directory]
truncation_length = 3
truncate_to_repo = false
[git_branch]
format = " on [$symbol$branch]($style) "
[cmd_duration]
min_time = 500
format = " ⏱ $duration "
Reload:
source ~/.bashrc
Starship is great if you want a maintained, cross-shell solution with minimal config.
4) Powerline: segmented, pretty prompts (with fonts)
Powerline draws a classic segmented status bar. You’ll want the Powerline fonts for proper symbols.
Install Powerline and fonts:
apt:
sudo apt update && sudo apt install -y powerline fonts-powerlinednf:
sudo dnf install -y powerline powerline-fontszypper:
sudo zypper install -y powerline powerline-fonts
Enable in ~/.bashrc:
if command -v powerline-daemon >/dev/null; then
powerline-daemon -q
POWERLINE_BASH_CONTINUATION=1
POWERLINE_BASH_SELECT=1
source /usr/share/powerline/bindings/bash/powerline.sh
fi
Use a Powerline-compatible font in your terminal profile to see the glyphs correctly. Powerline is themeable via JSON/JSONC configs and integrates well with tmux and Vim.
5) Context-aware prompts per host or project
Make dangerous or special contexts obvious.
Colorize root shells and SSH sessions (already shown in step 1 with
EUIDandSSH_TTY).Use direnv to set per-project variables the prompt can read.
Install direnv:
apt:
sudo apt update && sudo apt install -y direnvdnf:
sudo dnf install -y direnvzypper:
sudo zypper install -y direnv
Enable in ~/.bashrc:
eval "$(direnv hook bash)"
Example: tag a project with a short name and show it in your prompt without changing PS1 globally.
In your project directory:
echo 'export PROMPT_PROJECT="demo-api"' > .envrc
direnv allow
Then in your set_bash_prompt():
local proj=""
[ -n "$PROMPT_PROJECT" ] && proj="(\$PROMPT_PROJECT) "
PS1="${status}\[${cyan}${bold}\]${hostpart}\[${reset}\] "\
"\[${blue}\]\w\[${reset}\] ${proj}${venv}$(__git_ps1 ' [%s]')\n\$ "
Now only that directory shows “(demo-api)” in the prompt.
Practical tips
Keep it fast: Avoid running subshells or scanning large directories in
PROMPT_COMMAND. Prefer helpers like__git_ps1or Starship.Use a newline: Complex info reads better above the input line.
Test in a fresh shell:
bash --noprofile --norcthensource ~/.bashrcto isolate issues.Version control your shell dotfiles: Reproducible setups across hosts save time.
Conclusion and next steps
A good prompt template is like a HUD for your terminal—always-on, always-relevant. Start small with the pure Bash template, add Git awareness, then decide if Starship or Powerline suits your style. Finally, make production or project contexts unmistakable.
Your next step:
Paste the minimal Bash template into
~/.bashrc.Add
__git_ps1or turn on Starship.Tag one critical environment (prod, root, or a key project) with a louder prompt.
Once you feel the difference, you’ll never go back to a bare “user@host:~$”.