Setting a variable within a bash PS1

bash, ps1

Solution

The proper way is to use `PROMPT_COMMAND` like so:

prompt_cmd () {
    LAST_STATUS=$?
    PS1="$PS1USERCOLOR\u"
    PS1+="$COLOR_WHITE@"
    PS1+="$COLOR_GREEN\h"
    PS1+="$COLOR_WHITE:"
    PS1+="$COLOR_YELLOW\W"
    if type parse_git_branch > /dev/null 2>&1; then
        PS1+=$(parse_git_branch)
    fi
    if [[ $LAST_STATUS = 0 ]]; then
        PS1+="$COLOR_WHITE"
    else
        PS1+="$COLOR_RED"
    fi
    PS1+='\$'
    PS1+="$COLOR_WHITE"
}

Since `PROMPT_COMMAND` is evaluated prior to each prompt, you simply execute code that sets `PS1` they way you like for each prompt instance, rather than trying to embed deferred logic in the string itself.

A couple of notes:

- You must save `$?` in the first line of the code, before the value you want is overwritten.

- I use double quotes for most of the steps, except for `\$`; you could use `PS1+="\\\$"` if you like.

Problem

I'm trying to customize my bash prompt and I'm having trouble with a few conditionals. My current `PS1` looks like this. ``` export PS1="\ $PS1USERCOLOR\u\ $COLOR_WHITE@\ $COLOR_GREEN\h\ $COLOR_WHITE:\ $COLOR_YELLOW\W\ \`if type parse_git_branch > /dev/null 2>&1; then parse_git_branch; fi\`\ \`if [ \$? = 0 ]; then echo -e '$COLOR_WHITE'; else echo -e '$COLOR_RED'; fi\`\$\ $COLOR_WHITE" ``` The first 6 lines just set regular `PS1` stuff. Line 7 then calls a function to display the current git branch and status if applicable. Line 8 then tests the return code of the previous command and changes the colour of the `$` on the end. Line 9 sets the prompt back to white ready for the user's command. However line 8 is responding to the return code from line 7's function and not the previous command as I first expected. I've tried moving line 8 before line 7 and eveything works as it should. But I don't want line 8 before line 7, the `$` must be on the end. I've tried setting a variable earlier on to be the value of `$?` and then testing that variable like so ``` export PS1="\ \`RETURN=\$?\`\ $PS1USERCOLOR\u\ $COLOR_WHITE@\ $COLOR_GREEN\h\ $COLOR_WHITE:\ $COLOR_YELLOW\W\ \`if type parse_git_branch > /dev/null 2>&1; then parse_git_branch; fi\`\ \`if [ \$RETURN = 0 ]; then echo -e '$COLOR_WHITE'; else echo -e '$COLOR_RED'; fi\`\$\ $COLOR_WHITE" ``` But this doesn't work. Does anybody have any idea how to solve my problem?

Original source