退出bash开关语句

退出bash开关语句,bash,Bash,我编写了一个菜单驱动的bash脚本,它在while循环中使用开关盒来执行各种菜单选项。一切正常。现在我正试图通过对用户输入执行错误测试来改进程序,但我似乎无法让它工作 问题是我不知道如何正确地中断switch语句,而不中断while循环(以便用户可以重试) 当用户输入有效的月份值时,程序工作正常,但如果他们输入的数字大于13,则程序不会中断switch语句并再次重复循环,而是中断switch和while循环并停止运行。点击将终止case语句。试着什么都不做: a|A) echo "Choose

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

问题是我不知道如何正确地中断switch语句,而不中断while循环(以便用户可以重试)


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

点击
将终止case语句。试着什么都不做:

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

案例的主体
移动到函数中,您可以随意从函数中返回

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


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


尝试将
break
更改为
continue
,这将把控制发送回while循环的开始处。

在您的示例中,中断没有意义,您可以完全忽略else break语句

当代码在您可能中断的点之后运行时,就会出现问题。你会想写这样的东西

case $v in
a) if [ $x ]; then bla; else break; fi;
  some more stuff ;;
b) blablabla ;;
我通常做的是(因为创建一个函数与复制粘贴非常麻烦,而且当你阅读它在其他地方拥有一个函数时,它会破坏程序的流程)使用一个break变量(当你像我一样缺乏幽默感时,你可以调用brake来取乐)并在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

这应该可以做到:将代码包装在一个单程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

问题是当我有多个
if
语句,并且需要对用户输入运行多个测试时。即使第一个失败,编程逻辑仍将通过其他
if
语句继续运行,就好像没有任何错误一样。@Moses你能举一个多
if
s的例子吗?如果[test1]&&[test2],也许您可以像在
中那样与
&
结合使用;然后。。。;fi
是的,我可以这样做(对某些命令也是如此),但是当我需要3+条信息来执行单个操作时,
if test
语句变得非常长,非常快。一次执行一个验证要简单得多(特别是因为这样可以让我向用户反映具体的问题,而不仅仅是说“一个或多个输入不起作用…”@Moses:运行每个测试后,您可以使用
if[$?-eq 0];然后;运行_test2;fi
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
#! /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