2012-09-07 147 views
26

如何重试bash命令,直到其状态为好或达到超时?重试超时Bash命令

我最好的拍摄(我在寻找简单的东西):

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

你不想把'$?'的权利放在测试语句中 - 我认为这是一个错字,你真的想要'$ COMMAND_STATUS'吗? –

+0

@Grisha Levit:你说得对,我更新了这个问题 –

+0

这个表格有一个好处,那就是$ COMMAND_STATUS在执行后可用。 – AnneTheAgile

回答

37

您可以通过将command就在测试和做事情简单化有点不同递增位。否则脚本看起来很好:

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

至少在bash版本4.1.5中,您需要将睡眠行更改为 sleep $((NEXT_WAIT_TIME ++)) – Nightscape

+0

谢谢,修复了答案。 –

+6

好的解决方案,唯一的问题是最后一个“命令”失败后,你仍然需要睡4秒。不确定这是否可以避免,并保持代码紧凑。 – David

9

把一些工具放在一起。

重试:https://github.com/kadwanev/retry

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

然后看到最终通魔

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

检查退出状态/失败。

+0

管理单元:https://github.com/sky-shiny/retrycli – J0hnG4lt

9

重试机能的研究为:

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 

如果你想在你的脚本重试功能,你应该这样做:

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

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