变量中的 KSH 模式不起作用

变量中的 KSH 模式不起作用

有人可以解释一下为什么 Korn shell 中的模式(分配给变量)这样工作:

u@h:w$ pattern='file_[0-9][0-9]'
u@h:w$ ls $pattern
file_01  file_02  file_03

但它不适用于更智能的模式file_{2}([0-9])

$ pattern='file_{2}([0-9])'
$ ls $pattern
ls: file_{2}([0-9]): No such file or directory

答案1

这是有意为之,以避免破坏 POSIX 合规性(尽管最初是为了避免破坏 Bourne 兼容性)。

echo file_{2}([0-9])

在 Bourne/POSIX 中将是无效代码sh,因此ksh可以随意解释它。但:

pattern='file_{2}([0-9])'
echo $pattern

是有效的 Bourne/POSIXsh代码,并且根据 POSIX,旨在匹配名为file_{2}(0), file_{2}(1)...的文件

当扩展运算符是扩展的结果时,它们不可用,即使您使用:

echo @($pattern)

您需要使用eval,或者您也可以使用FIGNORE

FIGNORE="!($pattern)"; echo *

(请注意,它会影响隐藏文件的扩展,FIGNORE="@(.*|!($pattern))"如果您不希望 glob 扩展隐藏文件,请进行此操作)。

请注意,bash后来zsh采用了其中一些ksh扩展运算符(尽管不是唯一{x,y}(...)的),但它们以不同的方式解决了 POSIX 合规性/Bourne 兼容性:它们使这些扩展 glob 在所有上下文中都可用,但仅在启用特定选项时(kshglobin zshextglobin bash)。然而,这意味着他们很难在不破坏自己的向后兼容性的情况下添加更多运算符。例如,如果现在bash添加运算符,它可能会破坏期望返回 true 的{x,y}(...)脚本。a='{1}(2){3}'; [[ $a = $a ]]

相关内容