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 --->"
        BASH_PROMPT="[\t][\u][\w] -x->"


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, 2019 at 15:04

1 Answer 1


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


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


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .