Is it possible to pre-evaluate a value in bash's PS1?

bash, git

Solution

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 :)

Problem

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?

Original source