77

在流行的命令式语言中,一旦匹配了 case 语句,switch 语句通常会“下降”到下一个级别。

例子:

int a = 2;
switch(a)
{
   case 1:
      print "quick ";
   case 2: 
      print "brown ";
   case 3: 
      print "fox ";
      break;
   case 4:
      print "jumped ";
}

将打印“棕狐”。

但是 bash 中的相同代码

A=2
case $A in
2)
  echo "QUICK"
  ;&
2)
  echo "BROWN"
  ;&
3)
  echo "FOX"
  ;&
4)
  echo "JUMPED"
  ;&
esac

只打印“棕色”

如何使 bash 中的 case 语句“落入”第一个示例中的其余条件?

(编辑:Bash 版本 3.2.25, ;& 语句(来自 wiki)导致语法错误)

跑步:

测试.sh:

#!/bin/bash
A=2
case $A in
1)
  echo "QUICK"
  ;&
2)
  echo "BROWN"
  ;&
3)
  echo "FOX"
  ;&
esac

给出:

./test.sh:第 6 行:意外标记附近的语法错误 ;&';' ./test.sh:
line 6:

4

4 回答 4

54

;&and运算符是在 bash 4.0 中引入的;;&,所以如果你想坚持使用五年前的 bash 版本,你要么必须重复代码,要么使用ifs。

if (( a == 1)); then echo quick; fi
if (( a > 0 && a <= 2)); then echo brown; fi 
if (( a > 0 && a <= 3)); then echo fox; fi
if (( a == 4)); then echo jumped; fi

或找到其他方法来实现实际目标。

(附带说明,不要使用所有大写的变量名。您可能会覆盖特殊的 shell 变量或环境变量。)

于 2012-08-17T18:07:03.987 回答
48

试试这个:

case $VAR in
normal)
    echo "This doesn't do fallthrough"
    ;;
fallthrough)
    echo -n "This does "
    ;&
somethingelse)
    echo "fall-through"
    ;;
esac
于 2015-08-21T12:04:40.230 回答
12

Using;&不是很便携,因为它需要bash(不是ash,dash或任何其他最小的sh)并且它至少需要bash4.0 或更高版本(并非在所有系统上都可用,例如 macOS 10.14.6 仍然只提供 bash 3.2.57)。

我认为比很多if's 更容易阅读的解决方法是循环并修改 case var:

#!/bin/sh

A=2
A_BAK=$A
while [ -n "$A" ]; do
    case $A in
        1)
            echo "QUICK"
            A=2
            ;;

        2)
            echo "BROWN"
            A=3
            ;;

        3)
            echo "FOX"
            A=4
            ;;

        4)
            echo "JUMPED"
            A=""
            ;;
    esac
done
A=$A_BAK

这是一个概念证明:https ://www.onlinegdb.com/0ngLPXXn8

于 2019-04-30T19:34:00.993 回答
-1

带有 fallthrough 的 bash 开关,用函数和标志实现

#! /bin/sh

switch_fallthrough() {
  [ $# = 0 ] && { echo no value >&2; return; }
  local f= # fall through
  [ "$1" = 1 ] && { echo quick; f=1; }
  [ $f ] || [ "$1" = 2 ] && { echo brown; f=1; }
  [ $f ] || [ "$1" = 3 ] && { echo fox; return; }
  [ $f ] || [ "$1" = 4 ] && echo jumped
  return 1 # error = no case did match
}

switch_fallthrough "2"
# brown
# fox
于 2022-01-13T08:58:56.947 回答