Exit switch bash statement

I wrote a bash-driven menu-driven script that uses a switch case inside a while to execute various menu options. Everything works perfectly. Now I am trying to improve the program by performing error checking on the user input, but I cannot get it to work ...

The problem is that I don’t know how to break out of the switch statement correctly without breaking out of the while loop (so the user can try again).

 # 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 above 13, instead of breaking the switch statement and repeating the cycle again, the program breaks both the switch and the while loop and stops working.

+4
source share
5 answers

Move the body of this case to a function, and you can return to execute the function as desired.

 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 ;; 
+5
source

Press ;; completes the case statement. Do not try to do anything:

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

I think what you want to do with break : "Close this case statement and restart the while loop." However, case ... esac not a control flow operator (although it may smell like one) and does not pay attention to break .

Try changing break to continue , which sends control back to the beginning of the while loop.

+3
source

There are no gaps in your example; you can omit the break statement altogether.

The problem occurs when there is code that runs after the point where you might break. Do you want to write something like this

 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 copying problem, and basically it interrupts the program flow when you read it to have the function somewhere else) - use a break variable (which you can call the brake for fun, when you have a lame sense of humor, like me) and enclose “a few more things” in the expression if

 case $v in a) if [ $x ]; then bla; else brake="whatever that 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 
0
source

This should do the trick: wrap the code in a one-way loop:

 #! /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 
0
source

All Articles