powerbash

Documentation

powerbash is a single bash script that you source into your shell. The powerbash command configures it, everything it does is a POWERBASH_* environment variable, and [tab] completes all of it.

Requirements

Runs on Linux, macOS, and WSL.

Install

All three of these install into your own account. None of them need root. Prefer Homebrew where you have it — powerbash then upgrades along with everything else you have installed. The other two exist for machines that do not have it, and are equally supported.

Homebrew

brew install powerbash/powerbash/powerbash

Then add the line the caveats print to your startup file:

pb="$(brew --prefix powerbash)/share/powerbash/powerbash.sh"
echo "source $pb" >> ~/.bashrc

Install script

For machines without Homebrew.

curl -s https://get.powerbash.org | bash

Downloads the script to ~/.local/share/powerbash/, then either links it into ~/.bashrc.d/ if you have that directory or appends a marked block to your startup file. Run it again to upgrade. It refuses to run as root.

By hand

mkdir -p ~/.local/share/powerbash
cd ~/.local/share/powerbash
curl -LsO https://download.powerbash.org/powerbash.sh
echo 'source ~/.local/share/powerbash/powerbash.sh' >> ~/.bashrc

On macOS, Terminal.app and iTerm2 start login shells, which read ~/.bash_profile rather than ~/.bashrc. Use that file instead.

On Fedora and RHEL, the stock ~/.bashrc already loops over ~/.bashrc.d, so you can drop the script in there and skip the source line entirely:

mkdir -p ~/.bashrc.d
curl -Ls https://download.powerbash.org/powerbash.sh -o ~/.bashrc.d/powerbash.sh

Put the source line near the end of your startup file, so powerbash sees any PROMPT_COMMAND set by other tools and can cooperate with them. Then start a new shell, or run exec bash.

Multi-user installs

This is discouraged. A per-user install upgrades without root, affects only you, and lets everyone on the machine keep the prompt they want. A /etc/profile.d install does none of that, and there is no uninstaller for it.

If you still want one, it is Linux only — macOS has no /etc/profile.d loop:

sudo curl -Ls https://download.powerbash.org/powerbash.sh -o /etc/profile.d/z_powerbash.sh
sudo chmod 0644 /etc/profile.d/z_powerbash.sh

The z_ prefix is there to sort powerbash last. Scripts in /etc/profile.d/ are sourced in filename order, and some of them register their prompt hook by assigning to PROMPT_COMMAND rather than appending to it — GNOME Terminal's vte.sh is the one people hit. An assignment throws away every hook registered before it, so a plain powerbash.sh, sorting ahead of vte.sh, would be dropped and your prompt would simply never appear.

Since 2.0.0 this mostly takes care of itself. Bash 5.1 and newer allow PROMPT_COMMAND to be an array, and powerbash now creates one when nothing else has claimed the variable yet. Scripts like vte.sh check for that and append instead of assigning, so on bash 5.1+ the ordering no longer matters. Keep the prefix anyway: bash 5.0 and earlier — RHEL 8, Ubuntu 20.04 — cannot use an array PROMPT_COMMAND, and there the old race is still live.

Two caveats. On Debian and Ubuntu, /etc/profile.d/ is sourced only for login shells, so interactive non-login shells will not pick it up; Fedora and RHEL source it for both. And the script exits immediately when run under a non-bash shell such as dash, so it is safe to leave there either way.

Upgrading

Installed withUpgrade with
Homebrewbrew upgrade powerbash
Install scriptcurl -s https://get.powerbash.org | bash
By handRe-run the same curl command

Your saved settings are not touched by any of these.

prompt

powerbash prompt on       # enable the powerbash prompt
powerbash prompt off      # minimal '$ ' prompt
powerbash prompt system   # restore the prompt you had before powerbash

path

powerbash path off        # hide the path segment
powerbash path full       # /full/path/to/no/where
powerbash path working    # where (default)
powerbash path parted     # /full/.../no/where
powerbash path short      # ..ull/path/to/no/where
powerbash path mini       # /f/p/t/n/where

short truncates to POWERBASH_PATH_SHORT_LENGTH characters, 20 by default. Adjust it with:

powerbash path short add          # lengthen by 1
powerbash path short add 5        # lengthen by 5
powerbash path short subtract 5   # shorten by 5 (never below 1)

The current directory always renders as ~ when it is your home directory, in every mode.

git

powerbash git on
powerbash git off
powerbash git skip /mnt/:/net/   # skip git in these path prefixes
powerbash git timeout 1          # give up on git after 1 second
powerbash git timeout 0          # disable the timeout (default)

The segment shows the current branch name, or a tag or short SHA when the head is detached. + means the working tree has uncommitted changes; and count the commits by which the branch is ahead of and behind its remote.

See slow filesystems for when to reach for skip and timeout.

Other segments

powerbash user on|off              # username
powerbash host on|off|auto         # hostname (auto = only over ssh)
powerbash jobs on|off              # background job count
powerbash symbol on|off            # $ / # prompt symbol
powerbash rc on|off                # return code, shown when non-zero
powerbash py virtualenv on|off|icon|short

For py virtualenv: on shows the icon and the full environment name, short shows the icon and the first five characters, and icon shows only the icon. Conda environments are detected the same way as Python ones.

term

powerbash term xterm|xterm-256color|screen|screen-256color

Sets TERM and recomputes the color palette. powerbash uses the 256-color palette when the terminal reports 256 colors or more, and an 8-color palette otherwise.

The case you actually need this for: your terminal ships its own terminfo entry — Ghostty sets TERM=xterm-ghostty, WezTerm sets wezterm — and you SSH into a machine that does not have it. tput there cannot resolve the name, so powerbash renders a plain, uncolored prompt. Naming a TERM the remote does know brings the colors back:

powerbash term xterm-256color

help, version, reload

powerbash help      # usage
powerbash version   # version
powerbash reload    # re-source ~/.bashrc (or ~/.bash_profile)

Run powerbash help at any time for the full list, and use [tab] completion — it knows every subcommand and every value.

Configuration

Every setting is an environment variable. The powerbash command just sets them, so you can also set them directly in your startup file before sourcing powerbash.sh.

Variable Values Default
POWERBASH_USERon, offon
POWERBASH_HOSTon, off, autoauto
POWERBASH_PATHoff, full, working, parted, mini, shortworking
POWERBASH_PATH_SHORT_LENGTHpositive integer20
POWERBASH_GITon, offon
POWERBASH_GIT_SKIP_PATHScolon-separated path prefixes/mnt/ on WSL, otherwise empty
POWERBASH_GIT_TIMEOUTseconds, or empty/0 to disableempty
POWERBASH_JOBSon, offon
POWERBASH_SYMBOLon, offon
POWERBASH_RCon, offon
POWERBASH_PY_VIRTUALENVon, off, icon, shorton

Saving your settings

Changes made with the powerbash command apply to the current shell only. To keep them:

powerbash config save     # write settings to ~/.config/powerbashrc
powerbash config load     # re-read that file
powerbash config default  # delete the file and reset to defaults

~/.config/powerbashrc is loaded automatically at startup when it exists. It is a plain list of NAME=value lines, and only the variables in the table above are ever written or read back — the file is parsed, never sourced, so a hand-edited or tampered one cannot put anything else into your environment.

Performance on slow filesystems

Under WSL, git operations against the Windows filesystem (/mnt/c and friends) are far slower than on the Linux filesystem and can visibly delay the prompt. powerbash defaults POWERBASH_GIT_SKIP_PATHS to /mnt/ when it detects WSL, which suppresses the git segment there at no cost.

Three options, cheapest first:

powerbash git skip /mnt/    # no git lookup under these prefixes (free)
powerbash git timeout 1     # run git, but give up after 1 second
powerbash git off           # disable the git segment entirely

git timeout requires timeout from GNU coreutils. It is present on most Linux distributions; on macOS, brew install coreutils provides it as gtimeout, which powerbash finds on its own. Without either, the command tells you so rather than silently doing nothing.

The timeout costs roughly a millisecond per prompt with GNU timeout — but some other timeout implementations are far slower to start, in which case prefer git skip.

Uninstall

If you used the install script:

curl -s https://get.powerbash.org | bash -s -- uninstall

It removes the script, the symlink or the block it added to your startup file, and nothing else.

If you used Homebrew, brew uninstall powerbash, then delete the source line you added.

If you installed by hand, remove whichever file you created:

rm ~/.local/share/powerbash/powerbash.sh   # and the source line in ~/.bashrc
rm ~/.bashrc.d/powerbash.sh
sudo rm /etc/profile.d/z_powerbash.sh

Your saved settings persist independently of all of this. Remove them too if you want a clean slate:

rm ~/.config/powerbashrc