bash case语句可以级联吗?


29

我正在尝试做这样的事情:

case $level in
    3)
        echo "Level Three"

    2)
        echo "Level Two"

    1)
        echo "Level one"
        ;;
esac

如果$ level = 3,它将输出

Level Three
Level Two
Level One

而如果$ level = 1,则仅输出

Level One

但是当我尝试它时,syntax error near unexpected token ')'由于没有包含,我得到了错误;;

我知道的所有其他语言都允许这样做,有没有办法在bash中做到这一点?某种关键字的含义是“现在继续进行下一种情况,就好像它匹配了”?


2
如果您知道的每种语言都允许这样做,则您需要学习C及其模仿程序以外的语言。案例陈述的失败是C语言中的历史性设计事故,在某种程度上,它可以用更原则的语言生存下来。
吉尔斯(Gilles)'“ SO-不要邪恶”

Answers:


42

您需要使用;&而不是;;来获得彻底的行为:

#! /bin/bash
foo() {
    case "$1" in
        3)
            echo "Level Three"
            ;&
        2)
            echo "Level Two"
            ;&
        1)
            echo "Level One"
            ;;
        a)
            echo "Level a"
            ;&
        b)
            echo "Level b"
            ;&
        c)
            echo "Level c"
            ;;
    esac
}
echo 3:
foo 3
echo 2:
foo 2
echo a:
foo a
3:
Level Three
Level Two
Level one
2:
Level Two
Level one
a:
Level a
Level b
Level c

请参阅bash文档的“ 条件构造”部分。

另一个特殊标记是;;&,它:

使外壳测试下一个子句中的模式(如果有),并在成功匹配后执行任何关联的命令列表。

;; 永远是最终的,不再测试其他模式。

#! /bin/bash

foo() {
    case "$1" in
        *3*)
            echo "Level Three"
            ;;&
        *2*)
            echo "Level Two"
            ;;&
        *1*)
            echo "Level One"
            ;;&
    esac
}

echo 12:
foo 12
echo 13:
foo 13
echo 23:
foo 23
12:
Level Two
Level One
13:
Level Three
Level One
23:
Level Three
Level Two

18
可移植性说明:该语法不是POSIX。它来自,(从4.0版,2009年开始)和(从3.1.2版,1997年开始)ksh可用。是特定于bash的。kshbashzsh;;&
斯特凡Chazelas

4
还要注意的是zsh等效bash;;&;|(4.3.3,2007年加入)。
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.