do… while ou do… até no shell script do POSIX

13

Existe o bem conhecido loop while condition; do ...; done , mas existe um loop de estilo do... while que garanta pelo menos uma execução do bloco?

    
por Shawn J. Goff 02.01.2013 / 16:40

2 respostas

12

Uma versão muito versátil de um do ... while tem essa 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 é (nenhum valor definido para i ), o loop é executado 20 vezes.
Comentando a linha que define i para 16 i=16 , o loop é executado 4 vezes. Para i=16 , i=17 , i=18 e i=19 .

Se i estiver configurado para (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 ciclo até, ou seja: ser falso (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 
    
por 13.12.2015 / 07:19
17

Não existe nada ... while ou do ... até o loop, mas a mesma coisa pode ser feita assim:

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

para até:

until false; do
  ...
  condition && break
done
    
por 02.01.2013 / 16:40