Skip to main content
  1. Posts/

Creating Beautiful Bash Prompts

·403 words·2 mins·
Table of Contents

This post summarize how to change the Bash shell prompt to a better look. The end result is shown in the title image.

Bash Special escape sequence
#

To change the bash prompt, we can directly change PS1 variable. Some special escape sequences1 are predefined by Bash to have special meaning, e.g., \u means the current user name.

Set PS1 to [\u@\h \w] and start bash, the prompt looks like the following:

[jdhao@jdhao-MBP ~/Projects/trial_error]

Using colors
#

Colors are important for us to create beautiful prompts. For example, echo -e "\033[4;32mtest\033[0m" will print green test with underline effect. In this command, \033 is the octal representation of ESCAPE control character, which starts an ANSI escape code to control the terminal behavior. You can also use \x1b, which is the hex value of ESCAPE control character. See this post on how to use colors in terminal.

A little trick I learned is to define a color for easier reuse:

GREEN="\e[0;32m"
COLOR_NONE="\e[0m"

When we want to use a color, we can now use the new name instead of the lengthy and obscure escape code.

GREEN="\e[0;32m"
COLOR_NONE="\e[0m"

printf "${GREEN}Green text${COLOR_NONE}"

Putting all together – the use of PROMPT_COMMAND
#

We can of course write all the logic to set the PS1 variable in one command, but it could be messy and unreadable. Instead, we can set PS1 via the env variable PROMPT_COMMAND. The value of PROMPT_COMMAND will be executed by Bash as command each time before Bash tries to show the actual prompt.

The following Bash script shows my final working prompt configuration:

GRAY="\e[2;37m"
GREEN="\e[0;32m"
PURPLE="\e[1;35m"
COLOR_NONE="\e[0m"

# Detect whether the current directory is a git repository.
function is_git_repository() {
  git branch > /dev/null 2>&1
}

function set_git_branch () {
    # Note that for new repo without commit, git rev-parse --abbrev-ref HEAD
    # will error out.
    if git rev-parse --abbrev-ref HEAD > /dev/null 2>&1; then
        BRANCH=$(git rev-parse --abbrev-ref HEAD)
    else
        BRANCH="bare repo!"
    fi
}

function set_bash_prompt () {

    if is_git_repository; then
        set_git_branch
    else
        BRANCH=''
    fi

    PS1=""
    # set up user and host
    PS1+="${GRAY}\u@\h${COLOR_NONE} "
    # set up working directory
    PS1+="${GREEN}\w${COLOR_NONE} "
    # set up git branch
    PS1+="${GRAY}${BRANCH}${COLOR_NONE}\n"
    # set up prompt character
    PS1+="${PURPLE}>${COLOR_NONE} "
}

export PROMPT_COMMAND=set_bash_prompt

Ref:


  1. A list of escape sequences and their meanings can be found here↩︎

Related

Why don't settings inside bashrc or bash_profile take effect?
··1008 words·5 mins
Fzf Installation and Usage
··771 words·4 mins
为什么 .bash_profile 里面的设置不生效?
··307 words·2 mins