2012-09-07 15 views
26

Jak ponowić próbę wykonania komendy bash do momentu, gdy jej stan będzie poprawny lub do momentu osiągnięcia limitu czasu?Ponów próbę wykonania komendy Bash z limitem czasu

Mój najlepszy strzał (szukam czegoś prostszego):

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

Nie chcą wstaw "$?" w teście testowym - zakładam, że to literówka i naprawdę chcesz "$ COMMAND_STATUS"? –

+0

@Grisha Levit: masz rację, aktualizuję pytanie –

+0

ten formularz ma tę zaletę, że $ COMMAND_STATUS jest dostępny po wykonaniu. – AnneTheAgile

Odpowiedz

37

można uprościć nieco umieszczając command prawo w teście i robi zwiększa się nieco inaczej. W przeciwnym razie skrypt wygląda dobrze:

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

Przynajmniej w wersji bashowej 4.1.5 należy zmienić linię uśpienia na sleep $ ((NEXT_WAIT_TIME ++)) – Nightscape

+0

Dzięki, poprawiono w odpowiedzi. –

+6

Dobre rozwiązanie, jedynym problemem jest to, że po tym, jak ostatnie "polecenie" się nie powiedzie, nadal będziesz musiał spać przez 4 sekundy. Nie jestem pewien, czy można tego uniknąć i zachować ten zwarty kod. – David

9

Połączyć niektóre narzędzia.

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

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

Następnie zobaczyć magiczne

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 
... 

Sprawdź status wyjścia do ostatecznej pass/fail.

+0

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

9

ponawiania fuction jest od:

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 

jeśli chcesz ponowić funkcję w skrypcie, należy zrobić tak:

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

declare -fxr foo 
retry 3 timeout 60 bash -ce 'foo' 
Powiązane problemy