faça ... enquanto ou faça ... até no script shell POSIX

16

Existe o while condition; do ...; doneloop conhecido , mas existe um do... whileloop de estilo que garante pelo menos uma execução do bloco?

Shawn J. Goff
fonte
Muito obrigado Shawn, eu não esperava que a resposta se tornasse a resposta selecionada tão rápido. Então: obrigado pela seleção.

Respostas:

15

Uma versão muito versátil de a do ... whilepossui esta estrutura:

while 
      Commands ...
do :; done

Um exemplo é:

#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 "

Como é (sem valor definido i), o loop é executado 20 vezes.
UN-Comentando a linha que define i16 i=16, o loop é executado 4 vezes.
Por i=16, i=17, i=18e i=19.

Se i estiver definido como (digamos 26) no mesmo ponto (o início), os comandos ainda serão executados na primeira vez (até que o comando loop break seja testado).

O teste por um tempo deve ser verdadeiro (status de saída 0).
O teste deve ser revertido para um loop até, ou seja: seja falso (o status de saída não 0).

Uma versão POSIX precisa de vários elementos alterados para funcionar:

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 

fonte
Lembre-se de que se você usar set -ealgo que falhe dentro do bloco de condições while não interromperá a execução: por exemplo set -e; while nonexistentcmd; true; do echo "SHiiiiit"; exit 3; done- -> merda acontece. Portanto, se você usar isso, precisará ter muito cuidado com o tratamento de erros, ou seja, encadear todos os comandos &&!
Timo
17

Não há um loop de fazer ... enquanto ou fazer ... até, mas a mesma coisa pode ser realizada assim:

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

por até:

until false; do
  ...
  condition && break
done
Shawn J. Goff
fonte
Você pode usar qualquer uma das linhas de quebra com um dos loops - enquanto verdadeiro ou até falso, apenas significa 'para sempre'. Eu entendo que meio que preserva o tempo ou o tempo para ter a condição de saída feliz ou saída triste.
Android.weasel