script bash: répéter la commande si elle renvoie une erreur

Réponses:

40

J'ai trouvé la base de cette élégante boucle ailleurs sur serverfault. Il s'avère qu'il n'est pas nécessaire d'enregistrer le code de sortie, car vous pouvez tester directement sur la commande elle-même;

until ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file; do
  echo Tansfer disrupted, retrying in 10 seconds...
  sleep 10
done
Roy
la source
8

Presque. Vous feriez probablement mieux d'enregistrer la valeur de retour en tant que variable afin de pouvoir la prérégler avant la boucle. Sinon, il sera affecté par la commande de dernière exécution.

Vous voudrez peut-être également sleepy accrocher un pour l'empêcher de se reproduire trop rapidement.

RET=1
until [ ${RET} -eq 0 ]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
    RET=$?
    sleep 10
done
Dan Carley
la source
Je pense que j'ai oublié de passer le code de sortie à la variable RET, mais j'ai compris l'idée. Ma principale question est de savoir quand la clause jusqu'à sera évaluée. En C, il ne sera évalué qu'après la première exécution de la boucle, auquel cas ma boucle devrait fonctionner. Le vôtre est encore meilleur, car il permet des commandes intermédiaires telles que le sommeil. Merci!
Roy
Bien repéré. Je l'ai édité. La clause sera évaluée avant la première exécution. Donc, auparavant, il utiliserait le code retour de toute commande précédente. Les doubles égaux ne sont pas appliqués par Bash, mais il est recommandé de les utiliser.
Dan Carley
== est pour l'égalité des chaînes non numérique, bien que je ne pense pas que cela soit important dans ce cas ...
Kyle Brandt
Les égaux simples et doubles sont identiques. Mais il serait préférable d'utiliser l'égalité entière maintenant que vous le mentionnez.
Dan Carley
1
Vous n'avez pas besoin de tester le numéro de code de retour - vous pouvez simplement tester le code de retour du programme lui-même - jusqu'au programme; dors 3; terminé .
chris
3

Bit hacky mais ma solution était de simplement créer une fonction bash qui s'exécute si elle se termine avec un échec

function retry { the_command_you_want && echo "success" || (echo "fail" && retry) }; retry
Qwertie
la source
0

Vous pouvez faire une boucle pendant que votre commande renvoie une erreur:

    while [ -n $(ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file) ]; do
            sleep 1;
    done;
Andrés Rivas
la source
3
Cette réponse doit être expliquée.
kasperd
@kasperd explication ajoutée
Andrés Rivas