购物的危险

购物的危险

在另一个问题中,建议我使用

shopt -s extglob

解决一个问题。我的印象是应谨慎使用这些类型命令,也许是因为它们可能会对其他脚本产生不良影响。有人能谈谈这个吗?

答案1

shopt只影响运行该命令的 shell 的行为。如果您将其放入~/.bashrcthen,它将影响非登录交互式 shell 和通过 rsh/ssh 运行的命令(如果~/.bashrc源自~/.profile或 ,则登录 shell 也可能会受到影响~/.bash_profile)。

将环境变量设置BASHOPTSextglob将影响设置该环境变量时启动的所有交互式或非交互式 bash shell(除非它们被称为sh)。

交互式 shell 是您想要extglob设置的地方,因为那是您想要使用它的地方,因此~/.bashrc是放置它的好地方,以便在每个交互式 shell 中受益。如果您想在脚本中使用它,只需将其添加到脚本的开头即可。

唯一可能导致问题的地方是当它被设置时,而您没有编写的某些代码并不期望它被设置。例如,这可能是您的脚本来源在出现提示时或在~/.bashrc设置选项后。

虽然对于某些选项来说确实如此,但事实并非如此,因为extglob它是经过精心设计的(由 David Korn 设计,来自 ksh),以免破坏与 Bourne shell 的向后兼容性(并解释了为什么语法如此尴尬)。

基本上,任何使用扩展 glob 的内容在 Bourne shell 或 POSIX shell 语法中都会出现语法错误。如果 Bourne 或 POSIX 脚本有echo @(a),它将被破坏(因为未加引号的括号)。如果突然开始输出“a”而不是错误消息也没关系。

我不清楚为什么 bash 默认情况下不启用它,因为 bash 没有像 zsh 那样有任何其他替代的扩展 glob 语法。

编辑。虽然 David Korn 努力不破坏 Bourne/POSIX 兼容性,但 bash 看起来并不那么小心,这可能就是它不像 ksh 那样默认启用的原因。

在 ksh(以及 ksh 仿真中的 zsh)中,在参数或命令替换上执行通配符时,扩展通配符被禁用:

$ touch a
$ a='@(a)' ksh93 -c 'echo $a'
@(a)

而在 bash 中,情况并非如此:

$ a='@(a)' BASHOPTS=extglob bash -c 'echo $a'
a

相关内容