I need to make a bash prompt that uses the data returned by another function. I need the prompt to support colour.
Toy case:
fx() {
...some processing...
# x is the result of some processing
color=x
echo "\[$(tput setaf ${color})\]${data_from_processing}\[${tput sgr0}\]"
}
PS1='fx'
But the above solution doesn't seem to work. What I expected is 'data' in the specified color. But what I get is \[\]<the correct data>\[\]
. It should be noted that \]<the correct data\[
is in color.
The shell parses the value of PS1
(which includes recognizing the special escape sequences \[
and \]
) before the command substitution is evaluated.
The simplest fix is to replace \[
and \]
with the actual bytes that the shell would:
q() { printf '\001%s\002123\001%s\002' "$(tput setaf 1)" "$(tput sgr0)"; }
However, I would recommend using PROMPT_COMMAND
to assemble the value of PS1
rather than embedding a command substitution:
q () { echo "\[$(tput setaf 1)\]123\[$(tput sgr0)\]"; }
make_prompt () {
PS1="$(q):"
}
PROMPT_COMMAND=make_prompt
Of course, you can fold the definition of q
directly into the definition of make_prompt
if like. Note that we aren't delaying the call to q
; it is called immediately to create the value of PS1
to use for each prompt.