Comment exécuter une commande et obtenir son code de sortie en moins de caractères?


13

J'avais l'habitude d'écrire mes scripts comme ceci:

some_command
while [ $? -ne 0 ] ; do
    sleep 1
    some_command
done

Cela m'a toujours énervé de devoir écrire some_commanddeux fois. Puis-je le mettre d'une manière ou d'une autre dans la section de test de boucle?

Réponses:


20

Vous pouvez utiliser some_commandcomme condition de test.

while ! some_command; do sleep 1; done

La condition restera vraie tant qu'elle se some_commandtermine avec une erreur.

Ou d'une manière plus détaillée si vous souhaitez effectuer des vérifications supplémentaires:

while ! some_command
do 
    # add more if desired
    sleep 1
done

Cela a l'air mieux que le mien, même s'il s'agit d'un monoplace ;-)
Anthon

L'OP pourrait vouloir le diviser en plusieurs lignes s'il a besoin d'exécuter plusieurs commandes en cas d'échec :)
John WH Smith

Aucune raison pour laquelle vous ne pouvez pas le séparer au niveau des points-virgules pour le rendre multiligne.
Mark Stewart

1
... ou écrivezwhile ! some_command; do several; commands; sleep 1; done
ignis

12

Voici à quoi sert la untilboucle:

until some_command
do    sleep 1
done

C'est la négation logique d'une whileboucle.

La spécification dit:

La untilboucle

  • La untilboucle doit exécuter en continu une liste composée tant qu'une autre liste composée a un état de sortie non nul.

  • Le format de la boucle jusqu'à est le suivant:

    jusqu'à compound-list-1
    faire composé-liste-2
    terminé
  • Le composé-list-1 doit être exécuté, et s'il a un état de sortie nul, la untilcommande se termine. Sinon, la liste composée-2 doit être exécutée et le processus se répète.

4

Vous pouvez simplement faire:

false
while [ $? -ne 0 ] ; do
   sleep 1
   some_command
done

cela a cependant l'inconvénient qu'il dort toujours une seconde en premier

Si vous voulez pouvoir quitter l'une des nombreuses commandes pour quitter avec 0, vous pouvez faire:

while true; do
  if [ some_command ] ; then break ; fi
  if [ some_other_command ] ; then break ; fi
  sleep 1
done

qui bien sûr fonctionne aussi pour seulement some_command


5
Le deuxième exemple ne doit pas inclure [et ]autour des commandes.
nyuszika7h

2

Ni while ! ...ne until ...fonctionne sur les systèmes qui ont gelé leur environnement shell avant POSIX.1-2001. Cela, cependant, le fait.

while :; do
    if some command; then
        break
    fi
    sleep 1
done

Si vous n'avez pas besoin d'une portabilité totale, pourquoi écrivez-vous un script shell? Perl est plus susceptible d'être disponible que Bash.

sleep 1 while 0 != system qw(some command);

(Comme ci-dessus, le sleep n'est exécuté que si la commande échoue.)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.