When you’re working on your Linux or Mac OS X system’s command line, the prompt is the text to the left of the commands you enter. The default prompt varies for every system, but it usually gives you an indication of your username, your machine’s host name and your current working directory. Also, it ends with a dollar sign
$ if you’re working as a normal user. If you’re working with
root privileges, it ends with
The prompt can be customized to include relevant information that can help you increase productivity, to hide information you don’t care about, or to highlight the lines in your terminal output where you entered commands.
This post will show how to customize your
bash prompt, and, in the process, explain a few of its more advanced features that improve your productivity. Bash is the default shell on Mac OS X, available for all (or most) Linux distributions, if not already included, and available on Windows via Cygwin.
Bash primarily uses two variables that define how your prompt looks like:
PS1specifies the format of your regular prompt that appears to the left of every new command you type
PS2defines the continuation prompt: It appears when you enter a line ending with a backslash
to continue input on the next line.
In the following example, I split the
ls command over two input lines to show my system’s default
PS2 in action:
In this post’s monospaced example sections, an underscore will represent the cursor position when showing examples of a prompt, while a single
Saurus:~ danielbeck$ l > s Desktop Documents Downloads Library Movies Music Pictures Public Sites Saurus:~ danielbeck$ _
$character represents a generic prompt, except where otherwise noted.
As you can see, my
PS1 prompt contains
- the host name (Saurus),
- the current working directory (
~is a synonym to the user’s home directory),
- my username (danielbeck),
- and an indicator that I am a regular user (
The second line is my default continuation prompt: A greater-than sign, followed by a single space.
You can assign different values to your prompt right in your shell session, as shown below. The values you set this way will be reset once you close your session, so you can experiment freely with the examples in this post. Just restart your shell session to reset the prompt variables to your permanent default values.
Saurus:~ danielbeck$ PS1='my new prompt $ ' my new prompt $ _
To display the currently assigned values (e.g. for copying them to your bash configuration files), you can
echo these variables. The second line in the following example is the output of the command on the first line, the prompt is repeated after execution on the third line:
my new prompt $ echo $PS1 my new prompt $ my new prompt $ _
Once you start adding shell scripts and program invocations to your prompt (see Executing scripts and programs below), this will already contain evaluated expressions, so you should not rely on this alone.
Displaying additional information
Bash supports several placeholder sequences for certain kinds of information that are commonly displayed in a prompt. These take the format of a backslash
, followed usually by a single character. Of course, you can find a list of all possible placeholders in the bash manual. To re-create the default prompt shown above, one would enter the following:
$ PS1='\h:\W \u\$'
This prompt contains the host name, followed by a colon, followed by the current working directory, a space character, the user name, and the prompt indicator. As already mentioned above, it is a hash character
# if the user has
root privileges, and a dollar character
I’m currently on a Linux machine and the shell prompt is showing me the […] number of executed commands. My own computer doesn’t have this, how can I configure it?
The answer is the placeholder sequence
\#: It prints the command number of the command following it. The first command of a bash session starts at 1, and every subsequent command increases it by 1. In the following example,
PS1='\# \$ ':
Last login: Thu Aug 25 21:54:14 on ttys001 1 $ pwd /Users/danielbeck 2 $ pwd /Users/danielbeck 3 $ pwd /Users/danielbeck 4 $ _
A very similar sequence is
! which represents the history number of the command following it. You can execute the command on that line again by entering an exclamation mark, followed by that command’s history number.
$ PS1='\! \$ ' 1478 $ pwd /Users/danielbeck 1479 $ cd / 1480 $ !1478 pwd / 1481 $ _
As you can see, the command executed through history expansion of
!1478 is printed again (
pwd), and then executed, this time with different results.
Once your prompt grows in length, you might want to add a line break or two to it by adding
n at the appropriate positions.
The prompt, or parts of it, can also be a different color than the default. Doing this is a bit tricky though. There are another few special sequences used for this. Similar to HTML or other document markup languages, the highlighted parts are enclosed in a pair of special formatting sequences. For HTML, this would be the
tag pair. In bash, it looks like this:
This example produces the following output:
regular text \[\033[0;32m\] green text \[\033[m\] regular text again
The actual formatting code is enclosed, similar to angle brackets for HTML tags.
\] are special sequences that indicate non-printing sequences, so bash can ignore everything between them for length calculations (e.g. when wrapping output lines depending on the terminal width). Strictly speaking, they’re optional, but you don’t want to mess up your terminal’s line breaking behavior by skipping them.
\033 is another special sequence: The digits are octal and represent the ASCII character with the corresponding code, in this case Escape. It starts a terminal control escape sequence (
\033[…m) specifying font and color attributes. For a list of such escape sequences, see this web page.
We use two of these sequences:
\033[0;32mresets text formatting and makes the following output a regular green
\033[mis an "empty" sequence containing no formatting rules. It resets output formatting to its defaults.
This page provides a nice
PS1 (at the bottom) so you can see all colors and other formatting options as part of a single
PS1. Just be prepared to endure blinking text, if your terminal emulator can handle it.
bash debugging facilities, it's even possible to add these formatting rules to the commands you enter.
Executing scripts and programs
You can execute arbitrary CLI programs as part of displaying your prompt, adding their output to it. For example, you might not like the behavior of
\W to print
~ instead of the full path to your home directory. No problem, just run
pwd, enclosed in
$( ), instead:
Saurus:~ danielbeck$ PS1='\h:$( pwd ) \u\$ ' Saurus:/Users/danielbeck danielbeck$ _
We usually have a choice of enclosing strings in single or double quotation marks. Since
bash evaluates all expressions enclosed in
$( pwd ) here, as well as variables (e.g.
$PS1), when enclosed in double quotation marks, we need to make sure to put values assigned to
PS1 in single quotation marks now. It didn't make a difference earlier, but we want these commands to be evaluated every time
PS1 is printed by the shell, not just once when the value is assigned to
PS1. Just remember to always use single quotation marks and you won't run into this problem.
In my experience, it's sometimes easy to overlook non-zero return codes of more complex commands with many lines of output. To make sure I notice these possible errors, I can add the previous command's return code to my prompt, like with the following
PS1='$( RET=$?; if [ $RET != 0 ] ; then echo "rc: $RET"; fi )\n\$ '
As a side effect, your prompt will now always start with a blank line if the previous command returned
0. While you can add line breaks to your prompt by using the sequence
bash discards all other newlines that are a result of e.g. multi-line program return values.
If you want to have a multi-line output depending on some conditions, you need to put that part of your prompt into the variable
PROMPT_COMMAND. It is expected to contain a script that is executed just before
PS1 is printed. To continue with the previous example of program return codes, use the following:
PROMPT_COMMAND='RET=$?; if [ $RET != 0 ] ; then echo "rc: $RET"; fi' PS1='\$ '
This produces almost the same results as the previous example, except that executing programs with exit code 0 won't print an additional blank line now.
PROMPT_COMMAND again, you can assign it an empty value:
The following prompt is an example on how you could combine the various elements I mentioned above into a powerful and informative prompt. I've been using this prompt, or slight variations of it, for a few months now.
I'll start with
PROMPT_COMMAND, as its output appears first:
PROMPT_COMMAND='RET=$?; echo; if [ $RET != 0 ] ; then echo "rc: $RET"; fi; if [ "$PWD" != "$HOME" ]; then if [ $( ls -A | wc -l ) -lt 20 ]; then ls -mAF; fi; else ls -mF; fi'
- This reads the last command's return value, and if non-zero, prints it on a separate line.
- If the current working directory is not the home directory, and has fewer than 20 files and folders in it, list them. If the current working directory is the home directory, only list non-hidden files and folders.
The prompt itself:
PS1='\[\033[0;32m\]\u\[\033[00m\] in \[\033[0;32m\]$( pwd ) ($( OUT=$( ls -A | wc -l ); echo $OUT ) entries, $(( $( ls -A | wc -l ) - $( ls | wc -l ) )) hidden)\n\[\033[1;32m\]\# \! \$\[\033[;m\] '
- Print the user name,
- the full current working directory (i.e. no
- the numbers of both all and hidden files and folders in the current working directory,
- and on the next line, print the command and history numbers, and the root privileges indicator
On my Mac, it looks like this:
Through color highlighting, the prompt is easily visible between program invocations with lots of output. It prints the previous command's return code unless it's
0, and lists all files in the current directory if the file count is reasonably low. I prefer this to functions that combine
ls, as I can immediately see the changes to the current directory after program execution.
As I wrote at the beginning, your prompt is not kept across shell sessions when you simply set
PS2) in your shell. To keep your changes across sessions and restarts of your machine, add the relevant assignments of
PROMPT_COMMAND -- one per line -- to your
.bashrc file in your home directory (more on these files). Save the file, open a new bash session, and enjoy your custom prompt!