I'm trying to port some code from bash 5.1 to 4.2.46. One function which tries to strip color codes from a specifically formatted string stopped working.
This is a sample string text
in such format. I turn on extended globbing for this.
text="$(printf -- "%b%s%b" "\[\e[31m\]" "hello" "\[\e[0m\]")"
shopt -s extglob
In bash 5.1, this parameter expansion works to remove all the color codes and escape characters
bash-5.1$ echo "${text//$'\[\e'\[/}"
31m\]hello0m\]
bash-5.1$ echo "${text//$'\[\e'\[+([0-9])/}"
m\]hellom\]
bash-5.1$ echo "${text//$'\[\e'\[+([0-9])m$'\]'/}"
hello
In bash 4.2.46, I start getting a different behavior as I build up the parameter expansion.
bash-4.2.46$ echo "${text//$'\[\e'\[/}"
\31m\]hello\0m\]
bash-4.2.46$ echo "${text//$'\[\e'\[+([0-9])/}"
\[\]hello\[\] ## no longer matches because `+([0-9])` doesn't follow `\[`
The difference comes from this line: echo "${text//$'\[\e'\[/}"
bash-5.1: 31m\]hello0m\]
bash-4.2.46: \31m\]hello\0m\]
Here's what printf "%q" "${text//$'\[\e'\[/}"
shows:
bash-5.1: 31m\\\]hello0m\\\]
bash-4.2.46: \\31m\\\]hello\\0m\\\]
Where is the extra \
coming from in 4.2.26?
Even when I try to remove it, the pattern stops matching:
bash-4.2.46$ echo "${text//$'\[\e'\[\\/}"
\[\]hello\[\] ## no longer matches because `\\` doesn't follow `\[`
I'm guessing there may be a bug related to parameter expansion, backslash escaping, and extended globbing.
I am aiming to write code that works on bash 4.0 onward, so I'm looking for a workaround primarily. An explanation (bug report, etc.) to why the behavior difference happens would be great, though.
bashbug
. – Binghi