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