我通常在[[command,但我想在case命令中使用它。
#!/bin/bash
bash -version|head -1
# Test 1:
[[ apple79 == apple@(14|38|79|11) ]] && echo ok 1
# Test2:
case apple79 in apple@(14|38|79|11)) echo ok 2;; *) ;; esac
当我用.
命令在终端运行上述test.sh
时,一切正常。
. test.sh
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
ok 1
ok 2
但当我试着运行它时:
./t.sh
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
ok 1
./t.sh: line 6: syntax error near unexpected token `('
./t.sh: line 6: ` case apple79 in apple@(14|38|79|11)) echo ok 2;; *) ;; esac'
我收到了case命令的错误消息。我看过一些bash模式匹配文档,例如:https://www.linuxjournal.com/content/pattern-matching-bash但我对这个问题一无所知。
extglob
选项在[[ ... ]]
内部隐式启用以进行模式匹配,但您需要显式启用它才能将其与case
语句一起使用。
#!/bin/bash
shopt -s extglob
[[ apple79 == apple@(14|38|79|11) ]] && echo ok 1
case apple79 in apple@(14|38|79|11)) echo ok 2;; *) ;; esac
错误很可能是因为您在当前shell中打开了extglob
选项。因为源代码脚本采用当前shell的选项和扩展选项,所以它在源代码脚本时起作用。
但在执行./t.sh
时,您正在启动一个显式shell,默认情况下该shell没有打开该选项。由于带有==
的[[
运算符默认打开extglob
,因此它适用于第一个测试,但不适用于case
语句。要在脚本中显式启用该选项,请在脚本顶部执行shopt -s extglob
。
正如您在下面看到的,只有在启用了选项的情况下,该模式才能与case
一起使用。尝试从下面的命令中删除-O extglob
,您可以看到它不起作用。
bash -O extglob -c 'case apple79 in apple@(14|38|79|11)) echo ok 2;; *) ;; esac'
至于您的尝试失败的原因,请尝试在t.sh
中添加一行shopt extglob
,然后重复测试。您会注意到,当脚本来源时,您将看到extglob on
,对于已执行的案例,将获得extglob off
区别在于交互式和非交互式shell选项。默认情况下,extglob对于非交互式shell是关闭的,因此您可以执行以下操作:
bash -i t.sh
或添加
shopt -s extglob
在脚本的开头