bug-bash mailing list中的某个人有confirmed,这是一个错误。
如果有人感兴趣,可以在the latest commit to devel branch中找到修复程序。
而
bash -c 'echo "${1##*""}"' _ bar
打印一个空行,
bash -c 'echo "${1##*"${1##*}"}"' _ bar
打印bar
。
我不明白。 ${1##*}
扩展为空字符串,因此应将"${1##*}"
视为""
,但似乎bash并不这样认为。
在其他流行的sh
实现中似乎对此达成共识:
$ 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(带有或不带有--posix
)是唯一不符合此要求的
$ bash -c 'echo "${1##*"${1##*}"}"' _ bar
bar
在没有子字符串处理的情况下,行为符合预期:
$ bash -c 'echo "${1##*"${1+}"}"' _ bar
$ bash -c 'echo "${1##*"${2}"}"' _ bar
$ bash -c 'echo "${1##*"${2}"}"' _ bar ''
$
我真的很想知道是否有对此的解释,我在手册中找不到。这是错误还是对标准的误解?此行为记录在某处吗?
PS:我知道一种快速的解决方法是取消对内部PE的引用,但这不能回答我的问题,并且可能导致包含特殊字符的字符串导致不良结果。
答案 0 :(得分:2)
这不是答案
首先,我认为这是由于特殊的glob-rules,但最终,我认为这是bash中的错误。以下四个示例应该使您了解为什么我认为这是一个错误:
$ 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
案例1和案例3的引号不同。但是形式为${parameter##word}
的参数扩展使用路径名扩展规则来处理word
。因此*foo
和*"foo"
具有相同的行为,因为除非它们包含特殊的模式字符(*
,?
,...),否则可以忽略路径名扩展中的双引号。在以下示例中可以看到:
$ bash -c 'echo "${1##*${2%%b*r}}"' _ 'foobar' 'f*ob*r'
bar
$ bash -c 'echo "${1##*"${2%%b*r}"}"' _ 'foobar' 'f*ob*r'
foobar
如果是这种情况,为什么情况2和情况4的行为会有所不同?