The Internet makes a great library but a lousy school.

Tweakin' your Bash Prompt

Date/Time Permalink: 01/03/07 11:00:25 am
Category: HOWTOs and Guides

About a month after moving into my new Slackware install, I have finally gotten around to setting up my cool Bash prompt again... only this time it's perfect.

Pre-requisite reading: Bash Prompt HOWTO For those of you who have never explored the deep hacking that is possible from the simple world of the $PS1 variable, and are still cruising around your terminal with a blah default prompt like:

you%yourbox ~%>

the Bash Prompt HOWTO is the ultimate geek-out on the subject. It's a shame that the link to the BashPrompt package described in the guide doesn't seem to be up.

Now for my own custom hack:
In my prompt I like to see:

  • the date
  • the time
  • the full directory path
  • the exit status of the last command

the exit status thing is for installing packages, compiling source, and other bothersome situations where I'd need to type "echo $?" to find out (clearly) if what I just tried to do worked or not.

So far with all that, I'd have:

PS1=
"{\d | \T -> \w ...\$?}"

which looks like:

prompt example 1

...with some delimiters thrown in. Now, you can see that one problem is that my prompt will expand with the directory depth, pushing what I type to word-wrap before its time. So I include a \n to escape to a newline and a crazy, unique character to mark my place:

PS1=
"{\d | \T -> \w ...\$?}\nß "

The German sz-lig character always looked to me like an elegant letter "B" for "Bash". I get that by typing ALT-223 at the console, by the way. That leaves me here:

prompt example 2

Now, one more annoyance is that when scrolling back through screens of output, my prompt tends to get lost in a sea of text. A popular solution is to change the color of the prompt using ANSI escape sequences. The Bash-Prompt HOWTO gives many elegant examples of this, but here's my simple version:

PS1=
"{\[\033[1;33m\]\d | \T -> \w ...\$?\[\033[0m\]}\nß "

That gives me a bright yellow color like this:

prompt example 3

Now for the improvement since my last exercise in prompt-hacking: I've always wanted to make the prompt dynamically change color to red when I am in root login, even when I use su to hop back and forth... from either direction! I finally figured this out from some advice in the HOWTO, where you can make up a shell script to do some function, then include a call to the script in your prompt. The escape sequence for high-red is 1;31, so I dropped the following in my /bin folder:

#!/bin/bash

if [ "$UID" -eq "0" ]; then
echo 31
fi
if [ "$UID" -eq "500" ]; then
echo 33
fi

under the name of "user_color". Now for the final tweak: I put my prompt thusly:

PS1=
"{\[\033[1;\$(user_color)m\]\d | \T -> \w ...\$?\[\033[0m\]}\nß "

I save this string in ".bash_profile" for each login that I want it to apply to, and I'm ready to rumble:

prompt example 4

and that, ladies and gentlemen, was your hack-o-the-day. Because HOOKED ON PHONICS WORKED FOR MEEEEE!

EDIT: Through further testing, I have discovered that executing the color change function misleads the output $? function. So I moved the last-command value to the front of the prompt, before the color change. It now reads:

PS1=
"{..\$?..\[\033[1;\$(user_color)m\]\d | \T -> \w \[\033[0m\]}\nß "

UPDATE Several systems later, here's what it looks like as of 2013:

Still pretty much the same, except that I've expanded the 'user_color' function to turn purple when I'm logged into another machine via SSH.

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

suddenly the moon