2012-09-07 12 views
26

¿Cómo volver a intentar un comando bash hasta que su estado sea correcto o hasta que se alcance un tiempo de espera?Vuelva a intentar un comando Bash con tiempo de espera

Mi mejor disparo (estoy buscando algo más simple):

NEXT_WAIT_TIME=0 
COMMAND_STATUS=1 
until [ $COMMAND_STATUS -eq 0 || $NEXT_WAIT_TIME -eq 4 ]; do 
    command 
    COMMAND_STATUS=$? 
    sleep $NEXT_WAIT_TIME 
    let NEXT_WAIT_TIME=NEXT_WAIT_TIME+1 
done 
+0

Usted no quiere poner el '$?' a la derecha en la declaración de prueba - Supongo que es un error tipográfico y realmente quieres '$ COMMAND_STATUS' allí? –

+0

@Grisha Levit: tienes razón, actualizo la pregunta –

+0

este formulario tiene la ventaja de que $ COMMAND_STATUS está disponible después de la ejecución. – AnneTheAgile

Respuesta

37

Se puede simplificar las cosas un poco poniendo command justo en la prueba y hacer incrementa un poco diferente. De lo contrario, el script se ve bien:

NEXT_WAIT_TIME=0 
until command || [ $NEXT_WAIT_TIME -eq 4 ]; do 
    sleep $((NEXT_WAIT_TIME++)) 
done 
+4

Al menos en la versión 4.1.5 de bash, debe cambiar la línea de espera por sleep $ ((NEXT_WAIT_TIME ++)) – Nightscape

+0

Gracias, corregidos en la respuesta. –

+6

Buena solución, el único problema es que después de que falle el último "comando", aún tendrá que dormir durante 4 segundos. No estoy seguro si eso puede evitarse y mantener el código tan compacto. – David

9

Reúna algunas herramientas.

reintento: https://github.com/kadwanev/retry

tiempo de espera: http://manpages.courier-mta.org/htmlman1/timeout.1.html

luego ver la magia

retry timeout 3 ping google.com 

PING google.com (173.194.123.97): 56 data bytes 
64 bytes from 173.194.123.97: icmp_seq=0 ttl=55 time=13.982 ms 
64 bytes from 173.194.123.97: icmp_seq=1 ttl=55 time=44.857 ms 
64 bytes from 173.194.123.97: icmp_seq=2 ttl=55 time=64.187 ms 
Before retry #1: sleeping 0.3 seconds 
PING google.com (173.194.123.103): 56 data bytes 
64 bytes from 173.194.123.103: icmp_seq=0 ttl=55 time=56.549 ms 
64 bytes from 173.194.123.103: icmp_seq=1 ttl=55 time=60.220 ms 
64 bytes from 173.194.123.103: icmp_seq=2 ttl=55 time=8.872 ms 
Before retry #2: sleeping 0.6 seconds 
PING google.com (173.194.123.103): 56 data bytes 
64 bytes from 173.194.123.103: icmp_seq=0 ttl=55 time=25.819 ms 
64 bytes from 173.194.123.103: icmp_seq=1 ttl=55 time=16.382 ms 
64 bytes from 173.194.123.103: icmp_seq=2 ttl=55 time=3.224 ms 
Before retry #3: sleeping 1.2 seconds 
PING google.com (173.194.123.103): 56 data bytes 
64 bytes from 173.194.123.103: icmp_seq=0 ttl=55 time=58.438 ms 
64 bytes from 173.194.123.103: icmp_seq=1 ttl=55 time=94.828 ms 
64 bytes from 173.194.123.103: icmp_seq=2 ttl=55 time=61.075 ms 
Before retry #4: sleeping 2.4 seconds 
PING google.com (173.194.123.103): 56 data bytes 
64 bytes from 173.194.123.103: icmp_seq=0 ttl=55 time=43.361 ms 
64 bytes from 173.194.123.103: icmp_seq=1 ttl=55 time=32.171 ms 
... 

Comprobar estado de salida para el paso final/no pasa.

+0

Ajustar: https://github.com/sky-shiny/retrycli – J0hnG4lt

9

reintento fuction es de:

http://fahdshariff.blogspot.com/2014/02/retrying-commands-in-shell-scripts.html

#!/bin/bash 

# Retries a command on failure. 
# $1 - the max number of attempts 
# $2... - the command to run 
retry() { 
    local -r -i max_attempts="$1"; shift 
    local -r cmd="[email protected]" 
    local -i attempt_num=1 

    until $cmd 
    do 
     if ((attempt_num == max_attempts)) 
     then 
      echo "Attempt $attempt_num failed and there are no more attempts left!" 
      return 1 
     else 
      echo "Attempt $attempt_num failed! Trying again in $attempt_num seconds..." 
      sleep $((attempt_num++)) 
     fi 
    done 
} 

# example usage: 
retry 5 ls -ltr foo 

si desea volver a intentar una función en el script, debe hacerlo de esta manera:

# example usage: 
foo() 
{ 
    #whatever you want do. 
} 

declare -fxr foo 
retry 3 timeout 60 bash -ce 'foo' 
Cuestiones relacionadas