GREEN="\e[1;32m"
RED="\e[1;31m"
NONE="\e[m"
get_exit_status(){
es=$?
if [ $es -eq 0 ]
then
echo -e "${GREEN}${es}${NONE}"
else
echo -e "${RED}${es}${NONE}"
fi
}
get_path(){
#dummy function
echo "PATH"
}
PROMPT_COMMAND='exitStatus=$(get_exit_status)'
The following gives me the correct exitStatus but colour variables are not expanded:
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
However, the one below, gives me the colours but the exit status does not update:
PS1="${RED}\h $(get_path) ${exitStatus}${NONE} "
What is the right way to do this? How can I fix this so that the exitStatus and colours both work?
Best Answer
Gilles identified your main problem, but I wanted to try explaining it differently.
Bash interprets the special prompt escapes only before expanding any variables in the prompt. This means that using
\e
in a variable that is expanded from the prompt doesn't work, even though it does work directly inPS1
.For example, this works as expected, and gives red text:
But this doesn't, it just puts a literal
\e
in the prompt:If you want to store the color escapes in variables, you can use ANSI-C quoting (
$'...'
) to put a literal escape character in the variable.To do this, you can change your definition of
GREEN
,RED
, andNONE
, so their value is the actual escape sequence.If you do that, your first
PS1
with the single quotes should work:However, then you will have a second problem.
Try running that, then press Up Arrow, then Home, and your cursor will not go back to the start of the line.
To fix that, change
PS1
to include\[
and\]
around the color escape sequences, e.g.You can't use
get_exit_status
properly here, since its output contains both printing (the exit code) and non-printing characters (the color codes), and there's no way to mark it correctly in the prompt. Putting\[...\]
would mark it as non-printing in full, which is not correct. You'll have to change the function so that it only prints the proper color-code, and then surround it with\[...\]
in the prompt.