For a while now I've used colored prompts in bash. I typically make the machine name one color, the path another color, and the username bright red if I'm root. On some systems I show the date and time, the exit code of the previous command, whether I'm inside screen, or the ssh status. Other people have put the git branch, number of processes, job count, tty, system load, disk space, working files, or mailbox status into their prompts.

On the Mac though, once I upgraded to Leopard, the prompts interacted badly with the line-editing. I tried various things but just couldn't get them to work, and I really wanted line editing, so I gave up on the colored prompts.

However, I recently figured out a fix: set the language environment variable. Which one? I tried a few and ended up with this:

export LC_CTYPE=C

Does anyone know why this helps?

Here's how I set my bash prompt (from .bashrc):

# Username (if root or remote)
if [ "$(whoami)" = "root" ]; then
    PS1="\[\e[41;1;37m\] root"
elif [ -n "$SSH_CLIENT" ]; then
    PS1="\[\e[30;107m\]\u"
else
    PS1=""
fi

# Machine (if remote)
if [ -n "$SSH_CLIENT" ]; then
    PS1="$PS1@$hostname:"
fi

# Current directory
PS1="$PS1\[\e[34m\]\w/ \[\e[0m\]\$ "

# Current date and time
PS1="\[\e[0;90m\] \d \[\e[1m\]\t\[\e[0m\]\r\n$PS1"

# Screen name (if inside a screen)
if [ -n "$STY" ]; then
    PS1=" \[\e[32m\]$STY\[\e[0m\]$PS1"
fi

# Display a smiley for success/failure 
PS1="\`if [ \$? = 0 ]; then echo \[\e[42\;37m\]:\\);\
 else echo \[\e[41\;37m\]:\\(; fi\`\[\e[0m\] $PS1"

Now that I have colors working again, I'll probably read what other people have done and adopt interesting features.

Labels: ,

3 comments:

John wrote at Saturday, November 7, 2009 at 3:52:00 PM PST

Not sure if you heard this or not, but Jolt is shutting down your lil' bro's old game [earth]. What a run it had, and all because of your early work with SRE.

Unknown wrote at Monday, February 8, 2010 at 12:31:00 PM PST

I recently learned a much easier way to include escape characters in prompt strings, using the builtin "tput" command, which is an interface to the termcap/ncurses entries in an easier to parse way. For example, here's what I have for my PS1 string, which makes it much more readable:

PS1="\[$( tput setaf 0; tput setab 11)\] [\u@\h \W] \[$( tput sgr0 )\] "

"setaf" is "set forground"
"setab" is "set background"
"sgr0" is a "color reset" command.

I find that this style makes the prompt much more readable, and makes it easy to support 256-color terminals without much fuss. I also suspect that it's more compatible across different terminal types.

Anonymous wrote at Friday, March 26, 2010 at 6:24:00 AM PDT

thanks for the LC_CTYPE tip!