do… while lub do… do skryptu powłoki POSIX

16

Istnieje dobrze znana while condition; do ...; donepętla, ale czy istnieje do... whilepętla stylu, która gwarantuje co najmniej jedno wykonanie bloku?

Shawn J. Goff
źródło
Wielkie dzięki Shawn, nie spodziewałem się, że odpowiedź stanie się tak szybko odpowiedzią wybraną. Tak więc: dzięki za wybór.

Odpowiedzi:

15

Bardzo wszechstronna wersja do ... whilema tę strukturę:

while 
      Commands ...
do :; done

Przykładem jest:

#i=16
while
      echo "this command is executed at least once $i"
      : ${start=$i}              # capture the starting value of i
      # some other commands      # needed for the loop
      (( ++i < 20 ))             # Place the loop ending test here.
do :; done
echo "Final value of $i///$start"
echo "The loop was executed $(( i - start )) times "

W tej chwili (bez ustawionej wartości i) pętla wykonuje się 20 razy.
Komentując linię ustawioną ina 16 i=16, pętla jest wykonywana 4 razy.
Na i=16, i=17, i=18i i=19.

Jeśli i jest ustawione na (powiedzmy 26) w tym samym punkcie (na początku), polecenia będą nadal wykonywane po raz pierwszy (do momentu przetestowania polecenia przerwania pętli).

Test na chwilę powinien być prawdziwy (kod wyjścia 0).
Test powinien zostać odwrócony dla pętli kasowania, tj .: bądź fałszywy (status wyjścia inny niż 0).

Wersja POSIX wymaga zmiany kilku elementów do działania:

i=16
while
       echo "this command is executed at least once $i"
       : ${start=$i}              # capture the starting value of i
       # some other commands      # needed for the loop
       i="$((i+1))"               # increment the variable of the loop.
       [ "$i" -lt 20 ]            # test the limit of the loop.
do :;  done
echo "Final value of $i///$start"
echo "The loop was executed $(( i - start )) times "

./script.sh
this command is executed at least once 16
this command is executed at least once 17
this command is executed at least once 18
this command is executed at least once 19
Final value of 20///16
The loop was executed 4 times 

źródło
Pamiętaj, że jeśli użyjesz set -eczegoś, co zawiedzie w czasie, blok warunków nie zatrzyma wykonywania: np. set -e; while nonexistentcmd; true; do echo "SHiiiiit"; exit 3; done- dzieje się gówno. Tak więc, jeśli go użyjesz, musisz być bardzo ostrożny z obsługą błędów, tj. Połączyć wszystkie polecenia za pomocą &&!
Timo
17

Nie ma do zrobienia ... podczas lub robienia ... do pętli, ale to samo można osiągnąć w następujący sposób:

while true; do
  ...
  condition || break
done

do czasu:

until false; do
  ...
  condition && break
done
Shawn J. Goff
źródło
Możesz użyć dowolnej linii podziału z dowolną pętlą - podczas gdy prawda lub dopóki fałsz oznacza po prostu „na zawsze”. Rozumiem, że w pewnym sensie zachowuje on czasowość lub nieskończoność, aby mieć warunek szczęśliwego wyjścia lub smutnego wyjścia.
android.weasel