hacer ... mientras que o hacer ... hasta en el script de shell POSIX

16

Existe el while condition; do ...; doneciclo bien conocido , pero ¿existe un do... whileciclo de estilo que garantice al menos una ejecución del bloque?

Shawn J. Goff
fuente
Muchas gracias Shawn, no esperaba que la respuesta se convirtiera en la respuesta seleccionada tan rápido. Entonces: gracias por la selección.

Respuestas:

15

Una versión muy versátil de a do ... whiletiene esta estructura:

while 
      Commands ...
do :; done

Un ejemplo es:

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

Tal como está (sin valor establecido para i) el bucle se ejecuta 20 veces.
Sin comentar la línea que se establece ien 16 i=16, el bucle se ejecuta 4 veces.
Para i=16, i=17, i=18y i=19.

Si i se establece en (digamos 26) en el mismo punto (el inicio), los comandos aún se ejecutan la primera vez (hasta que se pruebe el comando loop break).

La prueba por un tiempo debe ser veraz (estado de salida de 0).
La prueba debe revertirse para un ciclo hasta, es decir: ser falso (estado de salida no 0).

Una versión POSIX necesita varios elementos cambiados 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 

fuente
Tenga en cuenta que si usa set -ealgo que falla dentro del bloque de condición while no va a detener la ejecución: por ejemplo, set -e; while nonexistentcmd; true; do echo "SHiiiiit"; exit 3; done-> sucede una mierda. Entonces, si usa esto, debe tener mucho cuidado con el manejo de errores, es decir, ¡encadenar todos los comandos con &&!
Timo
17

No hay un bucle do ... while o do ... while, pero se puede lograr lo mismo de esta manera:

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

para hasta:

until false; do
  ...
  condition && break
done
Shawn J. Goff
fuente
Puede usar cualquiera de las líneas de ruptura con cualquiera de los bucles, mientras que verdadero o hasta falso solo significa 'para siempre'. Entiendo que de alguna manera conserva el tiempo o el tiempo de tener la condición de salida feliz o salida triste.
android.weasel