Bash 带直通开关的开关盒?

Bash 带直通开关的开关盒?,bash,switch-statement,Bash,Switch Statement,我正在寻找Bash中带有错误案例的switch语句的正确语法(理想情况下不区分大小写)。 在PHP中,我将对其进行如下编程: switch($c) { case 1: do_this(); break; case 2: case 3: do_what_you_are_supposed_to_do(); break; default: do_nothing(); } 我希望Ba

我正在寻找Bash中带有错误案例的switch语句的正确语法(理想情况下不区分大小写)。 在PHP中,我将对其进行如下编程:

switch($c) {
    case 1:
        do_this();
        break;
     case 2:
     case 3:
        do_what_you_are_supposed_to_do();
        break;
     default:
        do_nothing(); 
}
我希望Bash中也有同样的功能:

case "$C" in
    "1")
        do_this()
        ;;
    "2")
    "3")
        do_what_you_are_supposed_to_do()
        ;;
    *)
        do_nothing();
        ;; 
esac
这在某种程度上是行不通的:当$C为2或3时,应该激发函数
do\u what\u you\u should\u to\u do()

使用竖条(
|
)表示“或”

  • 不要在bash中的函数名后面使用
    ()
    ,除非您想定义它们
  • 如果要匹配
    2
    3
  • 静态字符串大小写应该用
    '
    而不是
    '
如果包含在
”中,解释器(不必要)会在匹配之前尝试展开值中可能的变量

中的“$C”情况
'1')
你这样做吗
;;
[23])
做你应该做的事
;;
*)
什么也不做
;;
以撒
对于不区分大小写的匹配,可以使用字符类(如
[23]
):

中的“$C”情况
#将匹配C='Abra'和C='Abra'
[Aa]‘文胸’)
做一些神秘的事情
;;
#将匹配任何字符的所有字母大小写,如'abra'、'abra'或'abra'`
[Aa][Bb][Rr][Aa])
做些疯狂的、神秘的事情吗
;;
以撒
但是abra没有击中任何时候,因为它将与第一个病例相匹配


如果需要,可以省略
在第一种情况下继续测试以下情况下的匹配项。(
跳转到
esac

最近的
bash
版本允许通过使用
&而不是
:
它们还允许使用
;;恢复案例检查&那里

for n in 4 14 24 34
do
  echo -n "$n = "
  case "$n" in
   3? )
     echo -n thirty-
     ;;&   #resume (to find ?4 later )
   "24" )
     echo -n twenty-
     ;&   #fallthru
   "4" | [13]4)
     echo -n four 
     ;;&  # resume ( to find teen where needed )
   "14" )
     echo -n teen
  esac
  echo 
done
样本输出

4 = four
14 = fourteen
24 = twenty-four
34 = thirty-four
试试这个:

case $VAR in
normal)
    echo "This doesn't do fallthrough"
    ;;
special)
    echo -n "This does "
    ;&
fallthrough)
    echo "fall-through"
    ;;
esac

如果值是整数,则可以使用
[2-3]
[5,7,8]
来表示非连续值

#!/bin/bash
while [ $# -gt 0 ];
do
    case $1 in
    1)
        echo "one"
        ;;
    [2-3])
        echo "two or three"
        ;;
    [4-6])
        echo "four to six"
        ;;
    [7,9])
        echo "seven or nine"
        ;;
    *)
        echo "others"
        ;;
    esac
    shift
done
如果值是字符串,则可以使用
|

#!/bin/bash
while [ $# -gt 0 ];
do
    case $1 in
    "one")
        echo "one"
        ;;
    "two" | "three")
        echo "two or three"
        ;;
    *)
        echo "others"
        ;;
    esac
    shift
done

或者在这个简单的例子中,一个字符类
[23])
@mishka-我注意到你没有接受这个答案,是因为它没有回答问题的漏洞百出部分吗?如果在
做你应该做的事情之前应该进行特殊处理()
,将“2”和“3”折叠成一个单独的案例无法解决这一问题,则故障诊断逻辑非常有用。我不确定编辑问题以使其更清晰是否合理,因为很明显,许多人都认为这个答案很有用。@Tyson OP没有接受这个答案,因为它是一个未注册的用户。至于程序员通常理解的“直通”逻辑,问题体显示的是条件的崩溃,而不是直通逻辑。(请注意php代码中使用的
break
)此时编辑问题或其标题将使许多提供贯穿逻辑的答案无效,并且可能不应该这样做。直到其他用户多次编辑后,Fall through才出现在标题中,但现在将其删除为时已晚。如果大小写不重要,还可以在
中将C转换为小写的
大小写“${C,,}”,如果省略
;会发生什么?你不是应该使用
&;,则会出现语法错误我需要使用
&如果我想继续测试。这是一个非常有用的提示。至少对于bash4.3.11。我没有费心在其他人身上尝试过。注意:这对bash 3.2不起作用,它仍然是macOS中的默认bash。不要对parens使用调用函数!!!因为您可以在bash中使用
function fname{echo“Inside fname”;return 0;}
fname(){echo“Inside fname”;return 0;}
在函数调用上放置参数看起来就像是一个函数定义。函数的调用应与任何其他命令行程序一样,如
mv
cp
rsync
ls
cd
等。。。在这种情况下,我们这样调用fname:
fname$ARGS
dou\u nothing()
应该是一个SKIP语句吗?使用
。另请参见,(U&L.SE),(SO),(AskU)等。末尾的
shift
是什么?
shift
删除CLI参数列表中的第一个参数。基本上,在这个循环的每次迭代中,总是使用
$1
shift
的帮助下从CLI参数列表中获取每个参数。这个示例中的逻辑很难遵循。另外,我认为这个例子并没有真正说明
之间的区别&
&。我把
“24”
改成了
;&继续
并得到相同的结果,所以我仍然想知道你什么时候会使用
&故障。这是一个复杂事物的简单示例-我将
?4
更改为
[13]4
,以使其更加明显,并使您的更改成为macos bash上不支持的突破性更改:(@JerryGreen我能说什么,这是我的输出:
test.sh:line 7:unexpected token`&'test.sh:line 7:`;&#resume(稍后查找?4)
这是我的
bash--version
:GNU bash,version 3.2.57(1)-发布(x86_64-apple-darwin19)@v01pe哦,妈的,对不起。我每天在macos和windows之间切换10次(使用linux-like
MINGW64
shell),实际上我甚至没有意识到我在windows LOL上使用了这个脚本。只是在我的macbook上使用了同样的脚本(预安装)bash版本:我确认,它在windows上不起作用:\n尽管它显示了GNU bash,版本4.4.23(1)-发行版(x86_64-pc-msys)
,所以它似乎是较新的bash版本的一个功能:\Thx,顺便说一句!(由于信息错误,我删除了以前的评论)
#!/bin/bash
while [ $# -gt 0 ];
do
    case $1 in
    "one")
        echo "one"
        ;;
    "two" | "three")
        echo "two or three"
        ;;
    *)
        echo "others"
        ;;
    esac
    shift
done