Reputation: 50750
Someone in bug-bash mailing list has confirmed this is a bug.
If anyone's interested, a fix is available in the latest commit to devel branch.
While
bash -c 'echo "${1##*""}"' _ bar
prints an empty line,
bash -c 'echo "${1##*"${1##*}"}"' _ bar
prints bar
.
I don't understand this. ${1##*}
expands to an empty string, so "${1##*}"
should be treated just as ""
is, but seems like bash doesn't think so.
There seems to be a consensus on this among other popular sh
implementations:
$ sh -c 'echo "${1##*"${1##*}"}"' _ bar
$ ash -c 'echo "${1##*"${1##*}"}"' _ bar
$ dash -c 'echo "${1##*"${1##*}"}"' _ bar
$ ksh -c 'echo "${1##*"${1##*}"}"' _ bar
$ ksh93 -c 'echo "${1##*"${1##*}"}"' _ bar
$ mksh -c 'echo "${1##*"${1##*}"}"' _ bar
$ posh -c 'echo "${1##*"${1##*}"}"' _ bar
$ yash -c 'echo "${1##*"${1##*}"}"' _ bar
$ zsh -c 'echo "${1##*"${1##*}"}"' _ bar
$
bash (with or without --posix
) is the only one not conforming to that:
$ bash -c 'echo "${1##*"${1##*}"}"' _ bar
bar
And without substring processing thingies the behavior is as expected:
$ bash -c 'echo "${1##*"${1+}"}"' _ bar
$ bash -c 'echo "${1##*"${2}"}"' _ bar
$ bash -c 'echo "${1##*"${2}"}"' _ bar ''
$
I really wonder if there is an explanation for this, which I couldn't find in the manual. Is this a bug, or a misinterpretation of the standard? Is this behavior documented somewhere?
PS: I know a quick workaround is to unquote the inner PE, but that doesn't answer my question, and may lead to undesired results with strings containing special characters.
Upvotes: 10
Views: 381
Reputation: 26471
This is not an answer
First I was thinking that this is due to special glob-rules, but in the end I think this is a bug in bash. The following four examples should give you a feeling why I believe this is a bug:
$ bash -c 'echo "${1##*${1%%bar}}"' _ foobar # case 1
bar
$ bash -c 'echo "${1##*${1%%foobar}}"' _ foobar # case 2
$ bash -c 'echo "${1##*"${1%%bar}"}"' _ foobar # case 3
bar
$ bash -c 'echo "${1##*"${1%%foobar}"}"' _ foobar # case 4
foobar
Case 1 and case 3 differ in the quotes. But parameter expansion of the form ${parameter##word}
use pathname expansion rules to process word
. So *foo
and *"foo"
have identical behaviour as double-quotes in pathname expansion can be ignored unless they embrace special pattern characters (*
,?
,...). This is seen in the following example:
$ bash -c 'echo "${1##*${2%%b*r}}"' _ 'foobar' 'f*ob*r'
bar
$ bash -c 'echo "${1##*"${2%%b*r}"}"' _ 'foobar' 'f*ob*r'
foobar
So if this is the case, why should Case 2 and Case 4 behave differently?
Upvotes: 2