我在bash中的case命令中存在模式匹配问题



我通常在[[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

在脚本的开头

最新更新