退出 bash switch 语句
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7034838/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Exit a bash switch statement
提问by Moses
I've written a menu driven bash script that uses a switch case
inside of a while
loop to perform the various menu options. Everything works just fine. Now I'm trying to improve the program by performing error testing on the user input, but I cannot seem to make it work...
我编写了一个菜单驱动的 bash 脚本,它使用循环switch case
内部while
来执行各种菜单选项。一切正常。现在我试图通过对用户输入执行错误测试来改进程序,但我似乎无法让它工作......
The problem is I don't know how to properly break out of a switch statement, without breaking out of the while loop (so the user can try again).
问题是我不知道如何正确跳出 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
The program works fine when the user enters a valid month value, but if they enter a number higher than 13, instead of breaking the switch statement and repeating the loop again, the program breaks both the switch and while loop and stops running.
当用户输入有效的月份值时,程序运行良好,但如果输入的数字大于 13,则程序不会中断 switch 语句并再次重复循环,而是中断 switch 和 while 循环并停止运行。
回答by John Kugelman
Hitting ;;
will terminate the case statement. Try not doing anything at all:
点击;;
将终止 case 语句。尝试什么都不做:
a|A) echo "Choose a month"
read monthVal
if [ "$monthVal" -lt 13 ]
then
cal "$monthVal"
fi
;;
回答by glenn Hymanman
Move the body of that case
into a function, and you can return
from the function at will.
将它的主体移动case
到一个函数中,您可以随意return
从该函数中取出。
do_A_stuff() {
echo "Choose a month"
read monthVal
if [ "$monthVal" -lt 13 ]
then
cal "$monthVal"
else
return
fi
further tests ...
}
Then
然后
case $whatever in
a|A) do_A_stuff ;;
回答by Phil
I think what you mean to do with break
is "quit this case statement and restart the while loop". However, case ... esac
isn't a control-flow statement (although it may smell like one), and doesn't pay attention to break
.
我认为你的意思break
是“退出这个 case 语句并重新启动 while 循环”。然而,case ... esac
不是控制流语句(虽然它可能闻起来像一个),并且不注意break
.
Try changing break
into continue
, which will send control back to the start of the while loop.
尝试更改break
为continue
,这会将控制发送回 while 循环的开始。
回答by Lionel
In your example, there is no point in breaking, you can omit the else break statement altogether.
在您的示例中,中断没有意义,您可以完全省略 else break 语句。
The problem occurs when there is code that runs after the point where you would have broken. You'd want to write something like that
当代码在您可能会破坏的点之后运行时,就会出现问题。你想写这样的东西
case $v in
a) if [ $x ]; then bla; else break; fi;
some more stuff ;;
b) blablabla ;;
What I usually do (because creating a function is such a hassle with copy pasting, and mostly it breaks the flow of the program when you read it to have a function somewhere else) is to use a break variable (which you can call brake for fun when you have a lame sense of humor like me) and enclose "some more stuff" in an if statement
我通常做的(因为创建一个函数是复制粘贴的一个麻烦,而且当你阅读它以在其他地方拥有一个函数时,它通常会中断程序的流程)是使用一个中断变量(你可以调用它来刹车)当你像我一样有蹩脚的幽默感时会很有趣)并在 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
回答by Dumbled0re
This should do the trick: Wrap the code in a one-trip for-loop:
这应该可以解决问题:将代码包装在单程 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