17

In the script below - which prompts the user to confirm that they want to proceed with running a potentially bad script - when the user enters Y at the prompt - it will break out of the case block, only to be sent back into the while loop again.

#! /bin/bash
set -e

echo
echo "bad install start"
echo "-----------------------------------------"

while true; do
        read -p "this script will probably fail - do you want to run anyway?" yn
        case $yn in
                [Yy]*)
                        ##### WHAT GOES HERE?? #####
                        ;;
                [Nn]*)
                        exit ;;
                *)
                        echo "answer y or n" ;;
        esac

        echo "script has broken out of case back into while loop"
done

echo -e "\e[33m Installing bad packagename \e[0m"
apt-get install sdfsdfdfsd

echo "rest of script - will i keep running?"

When n is entered, the script exists entirely as desired. I'd like to know how to make it so that when Y is entered the script breaks out of both the case and the while block, but does not exit entirely. Is there something I can put in for the placeholder ("What goes here??") to do that?

closed as off-topic by glenn jackman, slm May 4 '15 at 20:22

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions describing a problem that can't be reproduced and seemingly went away on its own (or went away when a typo was fixed) are off-topic as they are unlikely to help future readers." – glenn jackman, slm
If this question can be reworded to fit the rules in the help center, please edit the question.

  • Note that first [Yn]*); you probably meant [Yy]*). – dhag May 4 '15 at 19:59
  • 1
    You edited your code since I first answered, but note in any case that $TEST=1 should be TEST=1, and your script is very likely to work with this change. – dhag May 4 '15 at 20:01
  • doh, yes I saw that when testing! – the_velour_fog May 4 '15 at 20:01
  • @dhag I think I've improved upon your edit—please take a look. It seems your goal is to rewrite the code into something where your accepted answer fits well, and I think it's closer now. – derobert May 4 '15 at 21:21
  • @derobert: Your edit looks fine to me; it certainly makes the question clearer. – dhag May 4 '15 at 21:25
29

In the case where the user entered "y", you can exit both while and case:

break [n]
       Exit from within a for, while, until, or select loop.  If  n  is
       specified, break n levels.  n must be ≥ 1.  If n is greater than
       the number of enclosing loops, all enclosing loops  are  exited.
       The  return  value is 0 unless n is not greater than or equal to
       1.

In your case, you want to do break 2.

  • 1
    thanks, yes break 2 did it, regarding your comment above, yes I tried setting a variable, but it didnt work - Im guessing bash has local scope within while and case blocks? unlike , for example PHP – the_velour_fog May 4 '15 at 20:04
  • No, bash variables aren't local (unless you explicitly declare them so), so assigning to TEST within the case as you did should be reflected in the test for the while loop. – dhag May 4 '15 at 20:05
  • ah got it, I was performing another assignment inside the [Yy] case block. made a little edit inside my question to reflect, but your right it works - thanks I learnt a couple of cool things! – the_velour_fog May 4 '15 at 20:11
  • In that case, break is enough. I don't see two levels of loops in the code. – xhienne Aug 6 '17 at 13:07
  • @xhienne: You appear to be correct! I'm not sure what I was thinking. – dhag Aug 6 '17 at 23:31
1

@dhag has a great answer. You can also use:

a=0
while [ "$a" -eq 0 ]; do
     ...
     [Nn]*)
          a=1;
          ;;
      ...
done

Not the answer you're looking for? Browse other questions tagged or ask your own question.