Date: Sat, 9 Aug 2025 01:35:17 +0200
From: Denys Vlasenko <[email protected]>
Message-ID: <[email protected]>
| # This isn't working in bash as expected
| echo '${a##$b?} removes \*: '"|${a##$b?}|"' - matches \, then one
char' # bash prints |\*bc|
| echo '${a##$b*} removes everything: '"|${a##$b*}|"' - matches \, then
all' # bash prints |\*bc|
| echo '${a##$b$c} removes everything: '"|${a##$b$c}|"' - matches \, then
all' # bash prints |\*bc|
| echo '${a##$b"$c"} removes \*: '"|${a##$b"$c"}|"' - matches \, then
*' # bash prints |\*bc|
| # the cause seems to be that $b emits backslash that "glues" onto next
character if there is one:
| # a='\*bc'; b='\'; c='*'; echo "|${a##?$b*}|" # bash prints |bc| - the $b*
works as \* (matches literal *)
| # a='\*bc'; b='\'; c='*'; echo "|${a##\\$b*}|" # bash prints |bc|
| # a='*bc'; b='\'; c='*'; echo "|${a##$b*}|" # bash prints |bc|
Why are you expecting anything different from what bash produces there?
Here there are no unspecified cases, the pattern is expanded first, so
taking just the first one:
${a##$b?}
expand the pattern (as it is unquoted), produca
${a##\?}
which is a perfectly valid glob expression to match a literal question mark.
There isn't one of those in $a so the match fails, nothing is removed. That
is exactly as it should be. The other 3 of those cases are explained the same
way. Any shell which isn't doing what bash is doing in those cases I'd say
is the shell with bugs.
kre