Bash 导致空字符串的参数扩展将以不同的方式处理 更新

Bash 导致空字符串的参数扩展将以不同的方式处理 更新,bash,Bash,有人在这是一个错误 如果有人感兴趣,可以在中找到修复程序 当 打印一条空行 bash -c 'echo "${1##*"${1##*}"}"' _ bar 打印条 我不明白${1##*}扩展为空字符串,因此“${1##*}”应该像“那样处理,但bash似乎不这么认为 在其他流行的sh实现中,似乎对此达成了共识: $ sh -c 'echo "${1##*"${1##*}"}"' _ bar $ ash -c 'echo "${1##*"${1##*}"}"' _ bar $ dash

有人在这是一个错误


如果有人感兴趣,可以在中找到修复程序


打印一条空行

bash -c 'echo "${1##*"${1##*}"}"' _ 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,但这并不能回答我的问题,并且可能会导致包含特殊字符的字符串产生不希望的结果

这不是答案

首先我认为这是由于特殊的glob规则,但最后我认为这是bash中的一个bug。以下四个示例应该让您感觉到为什么我认为这是一个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
案例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的行为会有所不同呢


gnubash,版本3.2.57(1)-release(x86_64-apple-darwin18)
打印一个空字符串
gnubash,版本4.4.12(1)-release(x86_64-pc-linux-GNU)
打印“bar”为什么案例2和案例4的行为不同?没有原因,
${1+}
${1+'}
都会扩展为空字符串,但它们的处理方式与
${1+}
不同(请参见我的最新编辑)。因此我们可以推断这是一个bug,对吗?@oguzismail,没错!如果案例1和案例3的行为相同,那么案例2和案例4的行为也应该相同。
$ bash -c 'echo "${1##*${2%%b*r}}"' _ 'foobar' 'f*ob*r'
bar
$ bash -c 'echo "${1##*"${2%%b*r}"}"' _ 'foobar' 'f*ob*r'
foobar