The issue is here:
PS1='...\[$ALERT_COLOR\]$exit_status ...\$ '
^^
That is a parameter expansion, it doesn't call the function you've set up.
You need to call the function within a command substitution, e.g. $(exit_status)
, or from PROMPT_COMMAND
. If you do, take care with the \[ .. \]
escapes: Bash interprets them before other expansions in the prompt, so you have to hardcode them in the prompt string (they can't be parts of variables or other things expanded in the prompt).
And if not expanding the prompt escapes from variables seems backwards to you, I can't blame you. But that's the way it's documented:
In addition, the following table describes the special characters which can appear in the prompt variables PS1
to PS4
: [...]
After the string is decoded, it is expanded via parameter expansion, command substitution, [...]
Something like this should work:
normal_color=$'\033[00m'
red_color=$'\033[41m'
exit_color=$normal_color
set_exit_color() {
if [ "$?" != 0 ]; then
exit_color=$red_color
else
exit_color=$normal_color
fi
}
PROMPT_COMMAND=set_exit_color
PS1='\[$exit_color\][$?]\[$normal_color\] \w\$ '
I would have thought it'd need a temporary variable to hold the exit status, but apparently PROMPT_COMMAND
doesn't modify the value of $?
that's expanded in the prompt. If call the function with a command substitution from inside the prompt string, then you need a workaround, as the exit code of the command substitution takes effect. Something like this:
normal_color=$'\033[00m'
red_color=$'\033[41m'
exit_color=$normal_color
exit_color() {
exit_code=$?
if [ "$exit_code" != 0 ]; then
echo "$red_color"
else
echo "$normal_color"
fi
return "$exit_code"
}
PS1='\[$(exit_color)\][$?]\[$normal_color\] \w\$ '
I would use the version with PROMPT_COMMAND
, just to save the subshell fork caused by the command substitution, but in practice the effect is minimal.
$?
in my PS1...", how did you do that? – JigglyNaga Sep 19 '18 at 13:33