Linux.com

Home Learn Linux Linux Tutorials How to Make a Fancy and Useful Bash Prompt in Linux

How to Make a Fancy and Useful Bash Prompt in Linux

We can program our humble Bash prompt to display all kinds of useful information, and pretty it up as well. We're sitting there staring at our computers all day long, so why not make it look nice? We will learn how to quickly test new configurations and quickly reverse them, how to make nice colors, how to display different types of information, customize it for different users, and make a multi-line prompt.

Configuring a different prompt for SSH sessions is one of my favorites, because it has saved me from many an error due to running a command in the wrong terminal. A dull life without broken servers is not too much to ask. Just add these lines to the ~/.bashrc of your user on the remote machine:

if [ -n "$SSH_CLIENT" ]; then text=" ssh-session"
fi
export PS1='\[\e[1;32m\]\u@\h:\w${text}$\[\e[m\] '

Then load your changes without logging out:

$ source ~/.bashrc

Now open an SSH session from another machine and you will see something like figure 1.

fig-1 green ssh prompt

You can even do all of this over SSH so you don't have to get up.

Colors

Of course you may choose from a multitude of splendid ANSI colors. You can find ANSI color code charts all over the place. These are the basic colors:

0;30m   Black
0;31m   Red
0;32m   Green
0;33m   Yellow
0;34m   Blue
0;35m   Purple
0;36m   Cyan
0;37m   White

0 is normal font. Change the 0 to 1 for bold, 4 for underline, and 5 for slow blink. In the SSH example text=" ssh-session" is whatever text string you want, and the text label is also arbitrary, as long as it matches ${text}.

The Bash shell supports a lot of special characters for customizing the prompt. For example, \u is the username, and \h is the hostname. Other useful special characters are:

\d : the date in "Weekday Month Date" format 
\t : the current time in 24-hour HH:MM:SS format
\w : the current working directory
\s : the name of the shell
\n : newline
\[ : begin a sequence of non-printing characters, for embedding a terminal control sequence into the prompt
\] : end a sequence of non-printing characters

Your custom prompt sequences are hard to read because of all the escapes, but you'll get the hang of it with a little practice. Note how the whole sequence is enclosed in single quotes, and it starts after PS1=. \u@\h: is an example of how to insert punctuation marks after the special characters. Literal punctuation marks are not escaped. You can insert spaces in the same manner; for example, see the closing color code, \[\e[m\] ', which has a space after last square bracket. This creates a space after the dollar sign. This example also shows how to reset the font color back to the terminal default. In the next example you'll see how to set a custom font color on right side of the prompt.

This example creates a pleasant cyan prompt with date and time (figure 2). Note also how you can add square brackets around the prompt, or any part of it, by enclosing the special characters with un-escaped brackets:

$ PS1='\[\e[1;34m\][\d \t \u@\h \w]\$\[\e[m\] '

fig-2 cyan prompt

You can go nuts with colors (figure 3):

$ PS1='\[\e[1;36m\]\d \[\e[1;32m\]\t \[\e[1;33m\]\u@\[\e[1;35m\]\h:\w\$\[\e[0;31m\] '

fig-3-colorful

Putting a color code at the end, like \[\e[0;31m\], sets a custom color on anything you type, and everything else that appears after the prompt.

Multi-line Prompt

Most terminals are 80 characters wide, so you run out of room when you have a long prompt. So why not break up the lines? You can with our old friend the newline special character, \n:

PS1='\[\e[1;33m\]\u@\h \w ->\n\[\e[1;36m\] \@ \d\$\[\e[m\] '

This creates a nice prompt with the username, current directory, and time and date (figure 4). It has an arrow to indicate there is another line, and it terminates in a proper dollar sign for an unprivileged user.

fig-4 multiline

Root Prompt

The root prompt is indicated by the hash mark, #. As long as we're making fancy prompts, why not make one for the root user too? Add these lines to both your ~/.bashrc, and to root's/root/.bashrc:

if [ $(id -u) -eq 0 ];
then
    PS1='\[\e[1;36m\][\d \t \u@\h \w]\$\[\e[m\] '
else
    PS1='\[\e[1;33m\][\d \t \u@\h \w]\$\[\e[m\] '
fi

You can either sudo or su to root, then source ~/.bashrc, and enjoy root's new fancy prompt. You can fancy up root's prompt just like for any user. A quick way to check any user's ID number is with the ID command:

$ id -u

Put a Fortune in your Prompt

Remember way back when we did Put a Talking Cow in Your Linux Message of the Day? You can also put one in your Bash prompt by adding this line to ~/.bashrc::

[[ "$PS1" ]] && /usr/games/fortune | /usr/games/cowsay -n

fig-5-fortune

~/.bashrc Gotchas

If there is not a ~/.bashrc then create one. On most distros it is sourced from ~/.profile, which you can verify by looking for something like these lines in ~/.profile:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
	. "$HOME/.bashrc"
    fi
fi

If your particular flavor of Linux does not use ~/.profile, then look for ~/.bash_profile or ~/.bash_login. If it doesn't have those then you have a weird Linux, and must consult your distro documentation to find out what to do.

Feeling lost? You can output your current prompt settings:

$ echo $PS1 

There are something like a billion and twelve ways to mess with your Bash prompt, so visit the Bash Reference Manual to learn all about it.

 

Comments

Subscribe to Comments Feed
  • Dharmit Said:

    I would prefer using zsh with oh-my-zsh. It's pretty awesome! :)

  • Juan Said:

    Let me show you mine: PS1="#\u@\h:\w:\[\033[01;32m\][\${PIPESTATUS[@]}]\[\033[00m\]\$ " The initial "#" is to avoid problems on copy/paste commands becoming them to comments. then:.. user@hots: full-current-path And... the cherry of the dessert: PIPESTATUS. This tells me the errorlevel of the previous executed command (or commands). While is zero, we are happy

  • ty Said:

    In classic linux fashion, should you want a offline reference check out the PROMPTING section (line 1964) in the man pages of bash --> man bash

  • nmset Said:

    How do we get back to default font attributes ? Suppose we want a different color for the host part only, everything afterwards should be in default attributes, without specifying a known color.

  • nmset Said:

    OK, found it in the writing, the closing color code : \[\e[m\]

  • test Said:

    Use [[ instead of [ in bash http://mywiki.wooledge.org/BashFAQ/031 http://mywiki.wooledge.org/BashGuide/TestsAndConditionals

  • Morten Juhl-Johansen Zölde-Fejér Said:

    I have been doing: PS1='\W \$ ' for years. Simple and clear, no more is necessary.

  • Chris F.A. Johnson Said:

    PS1='\e[0m\e[31;1m$PWD $BASH_VERSION $(date +%Y-%b-%d_%H:%M:%S)\e[30;1m\e[0m\n\$ '

  • Chris Said:

    Thanks - always find your articles interesting. I've been happy with this prompt for many years: PS1='\[\033[0;32m\]\u@\h\[\033[0m\] \[\033[0;33m\]\w\[\033[0m\]\n\[\033[1;33m\]\@\[\033[0m\]: ' Incidentally, you can instantly (and temporarily) test any new prompt simply by executing the following at your current prompt: > export PS1=...

  • vancho Said:

    PS1="\[\e[01;36m\]{\[\e[0m\]\[\e[01;32m\]\d\[\e[0m\]\[\e[00;36m\]}\[\e[0m\]\[\e[00;37m\]---\[\e[0m\]\[\e[01;35m\][\[\e[0m\]\[\e[01;32m\]\t\[\e[0m\]\[\e[01;35m\]]\[\e[0m\]\[\e[00;37m\]---\[\e[0m\]\[\e[01;36m\][\[\e[0m\]\[\e[01;33m\]\w\[\e[0m\]\[\e[01;36m\]]\[\e[0m\]\[\e[01;31m\]--->\[\e[0m\]"

  • mohamed Said:

    im totally new to linux, how did u guys go about learning this stuff, it seems soo awesome


Who we are ?

The Linux Foundation is a non-profit consortium dedicated to the growth of Linux.

More About the foundation...

Frequent Questions

Join / Linux Training / Board