Reputation: 9100
I'm trying to build a Bash prompt which will have both my git branch information (using __git_ps1 from git's bash-completion) and a little colored smiley to indicate whether the most recently run command was successful.
The smiley is created using this technique, which I found here on SO:
SMILEY="${GREEN}:)${COLOR_NONE}"
FROWNY="${RED}:(${COLOR_NONE}"
STATUS_EMOTICON="if [ \$? = 0 ]; then echo \"${SMILEY}\"; else echo \"${FROWNY}\"; fi"
Here's the prompt line I want to use:
export PS1="[\t]${RED}[\u@$MACHINE:${BOLD_CYAN}\w${GREEN}\$(__git_ps1 ' %s')${RED}]${COLOR_NONE} \`${STATUS_EMOTICON}\`\n$ "
Unfortunately, it looks like the programs that are run by __git_ps1 override the $?
value, and I end up with every emoticon being a green smiley, even after running false
.
Taking out the __git_ps1 call...
export PS1="[\t]${RED}[\u@$MACHINE:${BOLD_CYAN}\w${RED}]${COLOR_NONE} \`${STATUS_EMOTICON}\`\n$ "
...makes the emoticon work correctly.
So what I apparently need to do is evaluate ${STATUS_EMOTICON}
before running __git_ps1
, but include the evaluated value after __git_ps1
's output. Is that possible?
Upvotes: 4
Views: 622
Reputation: 20688
Don't put $(cmd)
or `cmd`
directly in your PS1
. Instead, use Bash's PROMPT_COMMAND
var. What I usually do is define a function _PS1_cmd
and set PROMPT_COMMAND=_PS1_cmd
. Then in _PS1_cmd
, I set misc vars I'd like to include in PS1
. For example:
THE-OLD-PROMPT # cat prompt.rc
function _PS1_cmd()
{
local saveExit=$?
# This non-zero exit will not affect $? on command line
g_git_ps1=$( echo TESTING; exit 1 )
if (( saveExit )); then
g_smiley=':('
else
g_smiley=':)'
fi
# Seems like this is not necessary, at least with bash 4.2.37. But
# to be safe, always return it.
return $saveExit
}
PROMPT_COMMAND=_PS1_cmd
PS1='$g_git_ps1 $g_smiley '
THE-OLD-PROMPT # source ./prompt.rc
TESTING :) ( exit 123 )
TESTING :( echo $?
123
TESTING :) echo $?
0
TESTING :)
Upvotes: 7