Jak mogę wyjść z pętli while z zagnieżdżonej instrukcji case? [Zamknięte]

18

W skrypcie poniżej - który zachęca użytkownika do potwierdzenia, że ​​chce kontynuować uruchamianie potencjalnie złego skryptu - gdy użytkownik wejdzie Yna monit - wyłamie się z casebloku, ale zostanie ponownie wysłany z powrotem do whilepętli.

#! /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?"

Po nwprowadzeniu skrypt istnieje całkowicie zgodnie z potrzebami. Chciałbym wiedzieć, jak to zrobić, aby po Ywprowadzeniu skrypt wyłamał się zarówno z bloku while, jak case i while, ale nie został całkowicie zamknięty. Czy jest coś, co mogę wstawić dla symbolu zastępczego („Co tu idzie?”), Aby to zrobić?

the_velour_fog
źródło
Zauważ, że najpierw [Yn]*); prawdopodobnie miałeś na myśli [Yy]*).
dhag
1
Edytowałeś swój kod od pierwszej odpowiedzi, ale zwróć uwagę, że tak $TEST=1powinno być TEST=1, a twój skrypt prawdopodobnie będzie działał z tą zmianą.
dhag
doh, tak, widziałem to podczas testów!
the_velour_fog
@dhag Myślę, że ulepszyłem twoją edycję - spójrz. Wydaje się, że Twoim celem jest przepisanie kodu na coś, w którym zaakceptowana odpowiedź pasuje dobrze, i myślę, że jest teraz bliżej.
derobert
@derobert: Twoja edycja wygląda dla mnie dobrze; z pewnością sprawia, że ​​pytanie jest jaśniejsze.
dhag

Odpowiedzi:

30

W przypadku, gdy użytkownik wprowadził „y”, możesz wyjść zarówno z chwili, jak i z przypadku:

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.

W twoim przypadku chcesz to zrobić break 2.

dhag
źródło
1
dzięki, tak, break 2zrobiłem to w odniesieniu do twojego komentarza powyżej, tak próbowałem ustawić zmienną, ale to nie zadziałało - Zgaduję, że bash ma zasięg lokalny w czasie i blokuje sprawy? w przeciwieństwie do np. PHP
the_velour_fog
Nie, zmienne bash nie są lokalne (chyba że je jawnie zadeklarujesz), więc przypisanie do TESTU w taki sposób, casejak to robiłeś, powinno zostać odzwierciedlone w teście dla pętli while.
dhag
Ach, rozumiem, wykonywałem kolejne zadanie w [Yy]bloku sprawy. wprowadziłem niewielką edycję w moim pytaniu, aby to odzwierciedlić, ale masz rację, działa - dzięki nauczyłem się kilku fajnych rzeczy!
the_velour_fog
W takim przypadku breakwystarczy. Nie widzę dwóch poziomów pętli w kodzie.
xhienne,
@xhienne: Wygląda na to, że masz rację! Nie jestem pewien, o czym myślałem.
dhag
1

@dhag ma świetną odpowiedź. Możesz także użyć:

a=0
while [ "$a" -eq 0 ]; do
     ...
     [Nn]*)
          a=1;
          ;;
      ...
done
doneal24
źródło