28

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?

5
  • Note that first [Yn]*); you probably meant [Yy]*). Commented May 4, 2015 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. Commented May 4, 2015 at 20:01
  • doh, yes I saw that when testing! Commented May 4, 2015 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. Commented May 4, 2015 at 21:21
  • @derobert: Your edit looks fine to me; it certainly makes the question clearer. Commented May 4, 2015 at 21:25

2 Answers 2

45

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.

5
  • 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 Commented May 4, 2015 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. Commented May 4, 2015 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! Commented May 4, 2015 at 20:11
  • 2
    In that case, break is enough. I don't see two levels of loops in the code. Commented Aug 6, 2017 at 13:07
  • @xhienne: You appear to be correct! I'm not sure what I was thinking. Commented Aug 6, 2017 at 23:31
1

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

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.