How to customize your bash prompt.

William Vincent
7 min readOct 21, 2021

Introduction

I love the terminal. The ability to quickly do tasks with a single command that would take a GUI user time to search through menus, find the right button, and multiple steps is such a satisfying experience. Having the full power of your computer at your fingertips is a blast. It doesn’t hurt that being proficient with the terminal makes you feel like you have entered the matrix doesn’t hurt either!

Customizing your terminal prompt can be a easy way to personalize your work environment and to increase your efficiency in some tasks. I have also found that I really enjoy changing up my prompt every so often and just tinkering with my work environment just for fun.

I hope that I can help to simplify the task of customizing your prompt and provide a useful reference for some of what you can do with a bash terminal.

Where is the PS1 variable stored?

If you are unfamiliar with bash entirely it can be a little confusing when someone says to look in the config file. The first challenge can be even finding the file due to bash config files being prepended with a dot, which makes it invisible in a file browser. The easiest way to find this file in Linux, Mac, and WSL is to open a terminal and make sure that you are in your home directory. The easiest way to make sure you are in the right location is to run cd with no arguments, this will by default take you to your home directory.

Once you are in the correct location, run the command ls -a. This will show you all of the files in your working directory, including hidden files. The file we will be working with is the .bashrc file, which is the file bash sources each time a terminal is opened for its configuration.

To open this file, use whatever text editor you are most comfortable with, and open the .bashrc file. Vim, Nano, VSCode, Sublime Text, and Atom are all readily available and quality text editors. Usually text editors have commands that will open a file directly from the terminal; vim .bashrc, code .bashrc, nano .bashrc for example.

Basics

Once you have found the file and have opened it in your favorite text editor you will want to find the line with export PS1="some crazy looking code", if you don’t have a line that defines your PS1 variable go ahead and write one. Just make sure that there isn’t a space between the variable name (PS1), the equal sign, and the quotes that will be the prompt definition.

I will be showing how to build the prompt that I use, which won’t be ideal for every single user, but I think it will work to show some different things that can be done with your prompt and introduce enough concepts that you will be able to design your own version.

Here is a list of options as it is shown in the bash manual

  • \a : A bell character.
  • \d : The date, in “Weekday Month Date” format (e.g., “Tue May 26”).
  • \D{format} : The format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required.
  • \e : An escape character.
  • \h : The hostname, up to the first ‘.’.
  • \H : The hostname.
  • \j : The number of jobs currently managed by the shell.
  • \l : The basename of the shell’s terminal device name.
  • \n : A newline.
  • \r : A carriage return.
  • \s : The name of the shell, the basename of $0 (the portion following the final slash).
  • \t : The time, in 24-hour HH:MM:SS format.
  • \T : The time, in 12-hour HH:MM:SS format.
  • \@ : The time, in 12-hour am/pm format.
  • \A : The time, in 24-hour HH:MM format.
  • \u : The username of the current user.
  • \v : The version of Bash (e.g., 2.00).
  • V : The release of Bash, version + patchlevel (e.g., 2.00.0).
  • \w : The current working directory, with $HOME abbreviated with a tilde (uses the $PROMPT_DIRTRIM variable).
  • \W : The basename of $PWD, with $HOME abbreviated with a tilde.
  • \! : The history number of this command.
  • \# : The command number of this command.
  • \$ : If the effective uid is 0, #, otherwise $.
  • \nnn : The character whose ASCII code is the octal value nnn.
  • \ : A backslash.
  • \[ : Begin a sequence of non-printing characters. This could be used to embed a terminal control sequence into the prompt.
  • \] : End a sequence of non-printing characters.

Here are a few simple examples of how this could be constructed.

Remember that every time you change the PS1 variable, in order to see the change, you will either need to close and reopen your terminal or run this command source ~/.bashrc. This will cause bash to reload the config.

A prompt with only the user.

export PS1="\u "

A prompt with the user and the full path separated by an @ sign.

export PS1="\u @ \w "

So from here on I will be showing step by step instructions on how to build the prompt that I daily drive.

I like to include the date and time in my prompt because I consistently forget what day it is and it can be nice to have that information readily available. I also like to wrap that information in square brackets to visually separate the information from the rest of my prompt.

export PS1="[\d / \@] "

I really hate having the entire path listed in my prompt but it is pretty critical to have the current directory listed, so I use the partial prompt.

export PS1="[\d / \@] \W "

I prefer multiline prompts because it gives me more room to write out lengthier commands without needing to wrap and doesn’t require me to reduce the amount of information displayed in the prompt. You can insert a newline by escaping cI have a arrow symbol representing that this is where commands I type will appear.

export PS1="[\d / \@] \W\n[=>] "

Next we will add the fun parts!

Displaying the current Git branch

Here is the function we will need to inject into our prompt in order for it to read the current git branch if we are in a git repository.

function parse_git_branch {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}

You can add this directly in the .bashrc file.

function parse_git_branch {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
export PS1="[\d / \@] \W \$(parse_git_branch)\n[=>] "

Adding Color to your prompt

Adding color to your prompt can add a lot of personality and make it easier to distinguish the information you are looking for at a glance. Here are the bash foreground color codes.

  • Black: 30
  • Blue: 34
  • Cyan: 36
  • Green: 32
  • Purple: 35
  • Red: 31
  • White: 37
  • Yellow: 33

I strongly recommend storing the colors you want to use in variables in your bash file just to keep the PS1 variable easier to read and make it less likely that you end up with errors in the prompt.

Color codes need to be wrapped in the non-printing character symbols. \[ and \] in order to work correctly and not cause annoying line wrap problems in your terminal.

Here is the colorized version of the prompt we have worked on so far!

green="\[\e[32m\]"
purple="\[\e[35m\]"
blue="\[\e[36m\]"
white="\[\e[00m\]"
function parse_git_branch {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
export PS1="${green}[\d / \@] ${purple}\W ${blue}\$(parse_git_branch)\n${green}[=>]${white} "

Conclusion

I hope that this has been helpful in introducing you to what can be done with your terminal prompt and given you enough information to design your own customized work environment. Happy hacking!

Check this out on my personal blog!

--

--