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?

Mihai
la source

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
John WH Smith
la source
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.
mikeserv
la source
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

Anthon
la source
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.)

zwol
la source