0

I'm trying to set my PS1 environment variable based on runtime condition, so I use the PROMPT_COMMAND to do so. Suppose I want to change my bash prompt based on $? value, my .bashrc would look like this:

function prompt_command() {
    if [ $? -eq 0 ]; then
        BASH_PROMPT="\W --->"
    else
        BASH_PROMPT="[\t][\u][\w] -x->"
    fi;
}

PROMPT_COMMAND=prompt_command
PS1='${BASH_PROMPT} '

I would like to make use of the Bash Prompt Escape Sequences. Unfortunately, this does not work because the values are displayed as is.

Also, I need to use an intermediate BASH_PROMPT variable because some tools are modifying the PS1 value. For example, while entering a virtual environment, (venv) is prepended to PS1, so I can't dynamically update PS1 in prompt_command because that would overwrite the (venv).

Why aren't these special values properly expanded and is there a workaround which does not imply spawning a subshell?

  • @Jesse_b BASH_PROMPT is set in prompt_command which is executed before each new line typed in my terminal, and before that the PS1 variable is displayed. The BASH_PROMPT variable is properly expanded in my shell, but not special values like \W and \t. – Delgan May 3 at 15:04
2

Why aren't these special values properly expanded?

man 1 bash says:

Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded […]

(in your case \t, \u, \w, \W)

After the string is decoded, it is expanded via parameter expansion, […]

So \t etc. are decoded first (but there are none in your PS1!), ${BASH_PROMPT} is expanded later. From this expansion your backslash-escaped special characters appear but it's too late for decoding.


Is there a workaround which does not imply spawning a subshell?

Yes. I found it here

Since Bash 4.4 you can use the @P expansion

Instead of PS1='${BASH_PROMPT} ' invoke

PS1='${BASH_PROMPT@P} '

Now $BASH_PROMPT will undergo additional decoding consistent with the PS1 original decoding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.