以下 Bash (v 5.1.4) 脚本
#!/usr/bin/env bash
echo $BASHOPTS
shopt extglob
x="123"
if [[ "$x" == +([[:digit:]]) ]]; then
echo "[[ Ok!"
fi
case $x in
+([[:digit:]])) echo "case Ok" ;;
*) echo case "KO" ;;
esac
输出
checkwinsize:cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
extglob off
[[ Ok!
./extglob_test.sh: line 10: syntax error near unexpected token `('
./extglob_test.sh: line 10: ` +([[:digit:]])) echo "case Ok" ;;'
这向我提出了几个问题:
shopt extglob
说它已关闭,因此第 9 行的 case 选项在逻辑上失败。但为什么第 5 行代码会成功呢?env 变量 BASHOPTS 包含继承的 shopt 选项,BASH 手册指出:
BASHOPTS A colon-separated list of enabled shell options. Each word in the list is a valid argument for the -s option to the shopt builtin command (see SHELL BUILTIN COMMANDS below). The options appearing in BASHOPTS are those reported as on by shopt. If this variable is in the environment when bash starts up, each shell option in the list will be enabled before reading any startup files. This variable is read-only.
所以我希望
extglob
在脚本中看到启用。事实上,echo $BASHOPTS
在 shell 提示符处发出命令会输出:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:histappend:interactive_comments:progcomp:promptvars:sourcepath
但是,我们可以看到存在一些差异,特别是此处存在的选项
extglob
,但在脚本的输出中缺失。当然,如果我启用脚本第 3 行中
extglob
的选项,我会得到:shopt -s extglob
checkwinsize:cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath [[ Ok! case Ok
然而,linter(我在 Vim 中使用 Ale)仍然在第 9 行发出语法错误信号
有任何想法吗?
答案1
有3个问题。
正如评论所说,
[[
默认情况下启用内部 extglob。您没有环境变量 BASHOPTS。您可以通过跑步
export | grep BASHOPTS
但看不到任何东西来看到这一点。正如你引用的那样“如果这个变量在 bash 启动时的环境中...”您需要export BASHOPTS
在交互式 shell 中运行。获得更好的短绒棉绒!