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
Run Code Online (Sandbox Code Playgroud)
prints an empty line,
bash -c 'echo "${1##*"${1##*}"}"' _ bar
Run Code Online (Sandbox Code Playgroud)
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
$
Run Code Online (Sandbox Code Playgroud)
bash (with or without --posix
) is the only one not conforming to that:
$ bash -c 'echo "${1##*"${1##*}"}"' _ bar
bar
Run Code Online (Sandbox Code Playgroud)
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 ''
$
Run Code Online (Sandbox Code Playgroud)
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.
这不是答案
首先我认为这是由于特殊的 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
Run Code Online (Sandbox Code Playgroud)
情况 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
Run Code Online (Sandbox Code Playgroud)
那么如果是这样的话,为什么案例 2 和案例 4 的表现会有所不同呢?
归档时间: |
|
查看次数: |
174 次 |
最近记录: |