我用我能找到的所有shell运行了以下命令(*sh
是sh
实现的名称);尽管我希望所有人都能打印match
,但结果却不一致。我不知道哪种行为是正确和可靠的。
*sh -c 'case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
使用dash from Ubuntu bionic's repo(和灰;这是短划线的符号链接)
$ dash -c 'case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
match
使用bash 4.4.20(1)-发行版(x86_64-pc-linux-gnu)和5.0.11(1)-发行版(arm-unknown-linux-androideabi)
$ bash -c 'case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
match
使用ksh版本AJM 93u + 2012-08-01和版本JM 93t + 2010-03-05(已随SunOS omniosce 5.11预先安装)
$ ksh -c 'case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
match
使用ksh @(#)PD KSH v5.2.14 99.07.13.2(OpenBSD 6.6和its Linux port上的默认shell)
$ ksh -c 'case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
$
使用lksh @(#)LEGACY KSH R56 2018/01/14,mksh @(#)MIRBSD KSH R56 2018/01/14(在Ubuntu bionic上这些是不同的二进制文件)和mksh @(#)MIRBSD KSH R57 2019/03/01
$ lksh -c 'case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
$ mksh -c 'case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
$
最高为0.13.1
$ posh -c 'case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
$
使用yash 2.46
$ yash -c 'case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
$
并使用zsh 5.4.2(x86_64-ubuntu-linux-gnu)和5.7.1(arm-unknown-linux-androideabi);模拟sh
$ zsh -c 'emulate sh; case "$1" in $2) echo match; esac' _ 'f\oo' 'f\\oo'
match
我迷失在POSIX's Shell Command Language specification †中;尚无法找到我的问题的简单答案:应如何以全局模式解释由变量扩展产生的转义反斜杠?是\\
还是\
?还是未指定?
†在Case Conditional Construct下显示:
按照从case语句的开始到结尾的顺序,每个标记化合物列表的 pattern 均应进行波浪号扩展,参数扩展,命令替换和算术扩展,并且根据{{3}}(还描述了引用部分模式的效果的描述),将这些扩展的结果与单词的扩展进行比较。
请注意,这并不是说模式会被删除引号;但是在模式匹配表示法下,它表示:
<反斜杠>字符应转义以下字符。转义的
应该被丢弃
但是并不清楚当模式是扩展结果时是否仍然会发生这种情况。
答案 0 :(得分:2)
也许此参考资料可以解决您的问题。子句在POSIX's Shell Command Language specification - under Pattern Matching Notation中指出,
2.13.1 匹配单个字符的模式
<backslash>
字符应转义以下字符。转义的<backslash>
将被丢弃。如果某个模式以未转义的<backslash>
结尾,则不确定该模式是否不匹配任何内容,或者该模式被视为无效
上述规则适用于使用case
语句和使用==
结构在bash
中使用test
全局匹配运算符的模式。
因此,由于您的$2
在进行模式匹配时保持无引号,因此f\\oo
的字面值将永远丢失并被解释为f\oo
。
为了清理起见,shell在引用删除期间保留了您的字面值,并且仅当在此模式匹配规则中应用传递的参数时,这种行为才会表现出来。