web-dev-qa-db-fra.com

Emulation d'une boucle do-while dans Bash

Quel est le meilleur moyen d'émuler une boucle do-while dans Bash?

Je pouvais vérifier la condition avant d'entrer dans la boucle while, puis continuer à revérifier la condition dans la boucle, mais c'est du code dupliqué. Y a-t-il un moyen plus propre?

Pseudo code de mon script:

while [ current_time <= $cutoff ]; do
    check_if_file_present
    #do other stuff
done

Cela n'effectue pas check_if_file_present s'il est lancé après le $cutoff heure, et ce que vous feriez bien.

118
Alex

Deux solutions simples:

  1. Exécutez votre code une fois avant la boucle while

    actions() {
       check_if_file_present
       # Do other stuff
    }
    
    actions #1st execution
    while [ current_time <= $cutoff ]; do
       actions # Loop execution
    done
    
  2. Ou:

    while : ; do
        actions
        [[ current_time <= $cutoff ]] || break
    done
    
191
jm666

Placez le corps de votre boucle après le while et avant le test. Le corps de la boucle while devrait être un no-op.

while 
    check_if_file_present
    #do other stuff
    (( current_time <= cutoff ))
do
    :
done

Au lieu des deux points, vous pouvez utiliser continue si vous trouvez cela plus lisible. Vous pouvez également insérer une commande qui ne lancera que entre itérations (pas avant le premier ou après le dernier), telle que echo "Retrying in five seconds"; sleep 5. Ou imprimez des délimiteurs entre les valeurs:

i=1; while printf '%d' "$((i++))"; (( i <= 4)); do printf ','; done; printf '\n'

J'ai changé le test pour utiliser des doubles parenthèses car vous semblez comparer des nombres entiers. À l'intérieur des doubles crochets, les opérateurs de comparaison tels que <= sont lexicaux et donnent un résultat erroné lors de la comparaison de 2 et 10, par exemple. Ces opérateurs ne travaillent pas entre crochets simples.

133

Au lieu des deux-points, vous pouvez utiliser continuer si vous trouvez que cela est plus lisible

Cette méthode imite la manière de faire les boucles Do-While que je cherchais - pour avoir le test de condition après les actions. J'ai également constaté que je pouvais placer un incrément d'index (si nécessaire) après l'instruction do, au lieu d'une instruction continue.

while 
    check_if_file_present
    #do other stuff
    (( current_time <= cutoff ))
do
    (( index++ ));
done
6
Randyman99