退出bash switch语句

时间:2011-08-12 01:44:34

标签: bash

我编写了一个菜单驱动的bash脚本,它使用switch case循环内的while来执行各种菜单选项。一切正常。现在我正在尝试通过对用户输入执行错误测试来改进程序,但我似乎无法使其工作......

问题是我不知道如何正确地突破switch语句,而不会打破while循环(这样用户可以再试一次)。

# repeat command line indefinitely until user quits
while [ "$done" != "true" ]
do
   # display menu options to user
   echo "Command Menu" # I cut out the menu options for brevity....

   # prompt user to enter command
   echo "Please select a letter:"
   read option

   # switch case for menu commands, accept both upper and lower case
   case "$option" in

   # sample case statement
   a|A) echo "Choose a month"
        read monthVal
        if [ "$monthVal" -lt 13 ]
        then 
           cal "$monthVal"
        else
           break # THIS DOES NOT WORK. BREAKS WHILE LOOP, NOT SWITCH!
        fi
        ;;
   q|Q) done="true" #ends while loop
        ;;
   *)   echo "Invalid option, choose again..."
        ;;
   esac
done
exit 0

当用户输入有效的月份值时,程序运行正常,但是如果他们输入的数字高于13,而不是打破switch语句并再次重复循环,程序会中断switch和while循环并停止运行

5 个答案:

答案 0 :(得分:9)

点击;;将终止案例陈述。尽量不要做任何事情:

a|A) echo "Choose a month"
     read monthVal
     if [ "$monthVal" -lt 13 ]
     then 
        cal "$monthVal"
     fi
     ;;

答案 1 :(得分:5)

case的正文移动到一个函数中,您可以随意从函数中return

do_A_stuff() {
    echo "Choose a month"
    read monthVal
    if [ "$monthVal" -lt 13 ]
    then 
       cal "$monthVal"
    else
       return
    fi
    further tests ...
}

然后

case $whatever in
a|A) do_A_stuff ;;

答案 2 :(得分:4)

我认为你对break的意思是“退出这个case语句并重启while循环”。但是,case ... esac不是控制流语句(虽然它可能闻起来像一个),并且不关注break

尝试将break更改为continue,这会将控件发送回while循环的开头。

答案 3 :(得分:0)

在你的例子中,没有任何意义,你可以完全省略else break语句。

如果代码在您破坏的点之后运行,则会出现问题。你想写那样的东西

case $v in
a) if [ $x ]; then bla; else break; fi;
  some more stuff ;;
b) blablabla ;;

我通常做的事情(因为创建一个函数是如此麻烦的复制粘贴,并且当你读取它以在其他地方有一个函数时,它主要打破了程序的流程)是使用break变量(你可以当你有像我这样的蹩脚的幽默感时,召唤刹车玩乐,并在if语句中附上“更多东西”

case $v in
a) if [ $x ]; then bla; else brake="whatever that's not an empty string"; fi;
   if [ -z "$brake" ];then some more stuff; brake=""; fi;; 
   #don't forget to clear brake if you may come back here later.
b) blablabla ;;
esac

答案 4 :(得分:0)

这应该可以解决问题:将代码换成一次性for循环:

#! /bin/bash

case foo in
  bar)
    echo "Should never get here."
    ;;

  foo)
    for just in this_once ; do
      echo "Top half only."
      if ! test foo = bar; then break; fi
      echo "Bottom half -- should never get here."
    done
    ;;

  *)
    echo "Should never get here either."
    ;;
esac