# My quest for the ultimate Bash prompt

On my new laptop (a Lenovo T61) I was still using the default Gentoo prompt in Bash. This was kind of a shame since my last Gentoo installation (on what is now my sister’s Ubuntu machine) had a beautifully customized prompt. It was time to dig up the old escape codes.

## The old

To recover my old prompt I didn’t even need to go rummaging through old files. All I had to do was to find an old forum post on the Gentoo forums. But, I noticed immediately that I didn’t like this old prompt so much anymore. It had too much stuff and it didn’t have very strong root warning signals.

My old Bash prompt

My old Bash prompt as root

## The new

My new Bash prompt

For my new prompt I used the PROMPT_COMMAND environment variable. The command in this environment variable is always run before the prompt is displayed. This means that, if you set the PS1 environment variable from this command, you can change your prompt depending on circumstances.

I pushed the dollar (or hash)-sign all the way to the left because I often type in very long commands. A little more space is used if there are background jobs, but only if there are background jobs.

My new Bash prompt with background jobs

You should never be root for too long, so I made being root very noticeable (and even slightly annoying):

My new Bash prompt as root (and with background jobs)

The following is the code I use to create the prompt. Stick it wherever you want it (e.g. in your user’s bashrc or in the system-wide bashrc) and adjust it to look nice and play nice with the rest of your environment. The code isn’t pretty, but it does what it has to. 😉

function prompt_command {
local XTERM_TITLE="\e]2;\u@\H:\w\a"

local BGJOBS_COLOR="$\e[1;30m$"
local BGJOBS=""
if [ "$(jobs | head -c1)" ]; then BGJOBS="$BGJOBS_COLOR(bg:\j)"; fi

local DOLLAR_COLOR="$\e[1;32m$"
if [[ ${EUID} == 0 ]] ; then DOLLAR_COLOR="$\e[1;31m$"; fi local DOLLAR="$DOLLAR_COLOR\\\$" local USER_COLOR="$\e[1;32m$" if [[${EUID} == 0 ]]; then USER_COLOR="$\e[41;1;32m$"; fi

PS1="$XTERM_TITLE$USER_COLOR\u$\e[1;32m$@\H:$\e[m$ $\e[1;34m$\w$\e[m$\n\
$DOLLAR$BGJOBS $\e[m$"
}
export PROMPT_COMMAND=prompt_command

If you want to learn more about customizing your prompt, there’s an article up at IBM’s website. From it, I stole this nice color table:

Console color codes table

Another tip: you can type man console_codes for everything about … console codes.

1. Comment by Gene
On February 15, 2009 at 01:09

cool. I’ve set up a prompt similar to yours which I really like now.
I found out that my prompt changes with 1 command lagging when I terminate a running job. This was cured with ‘set -b’ in .bashrc

2. Comment by halfgaar
On January 31, 2010 at 11:59

Just like you, I’ve been getting “bash: prompt_command: command not found” after running emerge. I think I know what causes it, but not how to fix it.

It is caused by the user which runs the compile scripts, user “portage” probably, that doesn’t have a a bash environment which loads the prompt_command function. I guess the PS1 and PROMPT_COMMAND vars are passed down to that user, but because it can’t find prompt_command (defined in the PROMPT_COMMAND var), it’s never updated. The reason I discovered this, is because when you su to a user which doesn’t have that PROMPT_COMMAND var, you get this message as well. If you do that from root, that user will have a red prompt, indicating it still has the PS1 that was calculated for root.

As for the solution, normally I would just put in in ~/.bashrc and source ~/.bashrc in ~/.bash_profile, but no shell is loaded for this user (shell is /bin/false). I’m open to suggestions…

3. Comment by Rowan Rodrik
On November 14, 2010 at 19:34

Thanks for the tip, Gene. 🙂