When putting ANSI color codes in PS1
, they need to be surrounded with \[\]
or else the prompt can get confused about where the editable part of the line starts. However, when a subcommand ($()
) prints colors, the \[\]
escapes are always being written literally to the prompt...and with long enough commands in my history, the prompt gets confused.
Here's an example:
ps1test() {
ps1sub() {
printf '\[\033[32m\]Hello!\[\033[0m\]'
}
PS1='$(ps1sub) \$ '
}
Expected:
$ ps1test
Hello! $
Actual (bash
installed by Git for Windows):
$ ps1test
\[\]Hello!\[\] $
How can I get my shell to interpret the \[\]
escapes from a subcommand?
Only \[
s in the literal string are interpreted. \[
s resulting from embedded expansions are not.
The easiest way to get around it is to have PROMPT_COMMAND
set a PS1
to a new literal value each time:
updateps1() {
ps1sub() {
printf '\[\033[32m\]Hello $RANDOM!\[\033[0m\]'
}
PS1="$(ps1sub) \\\$ "
}
PROMPT_COMMAND='updateps1'