I'm new to Bash programming, and I'm working on creating a custom Bash command prompt. My goal is to create a prompt which only shows the login name and host name when they differ from what I normally use. I'm also looking to append the current Git branch to the command prompt when in a directory which is under Git version control.
I would like to color the login and host name section green, the directory path blue, the Git branch section pink, and separators (: and $ characters) white. However, when the previously executed command returns anything other than zero, I would like to color the $ separator red. The general format without colors looks like this:
loginname@hostname:~/current/path:branchname$
The only sections that are mandatory are the directory path and the $ character. Here's the code I've written for my .bashrc file:
MYNAME="gwen"
MYHOST="gwen-laptop"
RED="\[\033[31m\]"
WHITE="\[\033[0m\]"
GREEN="\[\033[01;32m\]"
BLUE="\[\033[01;34m\]"
PINK="\[\033[01;35m\]"
DOLLAR="if [ \$? = 0 ]; then echo ${WHITE}\$; else echo ${RED}\$${NORMAL}; fi"
GITBRN='$(__git_ps1 "\033[0m:\033[01;35m%s")'
USERNM="if [ \u != ${MYNAME} ]; then whoami; fi;"
HOSTNM="if [ \h != ${MYHOST} ]; then echo -n @; hostname; fi;"
COLONM="if [ \u != ${MYNAME} ] || [ \h != ${MYHOST} ]; then echo -n :; fi;"
PS1="${GREEN}\`${USERNM}\`\`${HOSTNM}\`${WHITE}\`${COLONM}\`${BLUE}\w${GITBRN}\`${DOLLAR}\` "
This code meets all of my requirements, except that it leaves the $ character white at all times, and does not color it red at the appropriate times. (I suspect the problem is that the "\$?" in DOLLAR references the previously executed command, but DOLLAR is executed last when constructing PS1, so the previously execute statement is no longer the command which was run before PS1 construction began; it's something which was executed in order to create the command prompt.) I'm not sure how to solve this problem.
This code is ugly and needs to be refactored. I was trying to move all the color codes into their own variables, but when I used these color variables in the code for GITBRN, thing went haywire, so I ended up using literal colors there instead.
I've spent an entire day trying to get this code working, and I think I'm going nowhere at this point. Any suggestions for how to get that dollar sign colored red at the appropriate time would be most appreciated. I'm also open to suggestion on refactoring the code to make it cleaner and more readable.
P.S. I'm a Ubuntu Linux (Lucid Lynx) user.
Change the line set prompt="$user on `hostname`> " to set prompt="%".
Use the PROMPT_COMMAND
variable, which is executed before each primary prompt according to the bash man page.
For example (this doesn't work yet, I'm trying to get it working right, but I think it's possible):
PROMPT_COMMAND="if [ \$? = 0 ]; then DOLLAR="${WHITE}\$${NORMAL}"; else DOLLAR="${RED}\$${NORMAL}"; fi"
Edit: due to frustrations with executing commands and nonprinting characters inside PS1
(the \[
and \]
sometimes get printed out literally instead of used as hints to PS1
), I've come up with this (replace ...
with whatever you want in your prompt):
PROMPT_COMMAND='if [ $? = 0 ]; then DOLLAR_COLOR="\033[0m"; else DOLLAR_COLOR="\033[31m"; fi'
PS1='...\[$(echo -ne $DOLLAR_COLOR)\]$\[\033[m\] '
Of course, using $()
you could put whichever parts of this you like inside PS1
instead of using PROMPT_COMMAND
, I just like it this way so that PROMPT_COMMAND
contains the logic and PS1
contains the display commands.
I got it to work:
PROMPT_COMMAND='if [ $? = 0 ]; then PS1="\[\e[32;1m\]\u@\[\e[0m\e[30;47m\]\H\[\e[0m\]:\[\e[34;1m\]\w\[\e[0m\]$ "; else PS1="\[\e[31;1m\]\u@\[\e[0m\e[31;47m\]\H\[\e[0m\]:\[\e[31;1m\]\w\[\e[0m\]$ "; fi'
Standing on the sholders of @jtbandes. @jtbandes is the original author of the idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With