diff --git a/bin/bin/retry.sh b/bin/bin/retry.sh new file mode 100755 index 0000000..3e0758d --- /dev/null +++ b/bin/bin/retry.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +# Retries a command on failure. + +HELP=\ +"$0: $0 [flags] [options] [--] COMMAND + Runs a command, retrying if the command fails + + Arguments: + COMMAND The command to run + + Flags: + -h, --help Display this message and exit + --forever Retry until the command succeeds + + Options: + -n, --num-attempts number The maximum number of times to retry the command (default: 10) + -d, --delay number The number of seconds to wait between attempts (default: 3)" + +sleep_duration=3 +num_attempts=10 +params="" +forever="" + +while (( "$#" )); +do + case "$1" in + -h|--help) + echo "$HELP" + exit 0 + ;; + --forever) + forever=true + shift + ;; + -d|--delay) + sleep_duration="$2" + shift 2 + ;; + -n|--num-attempts) + num_attempts="$2" + shift 2 + ;; + --) + shift 1 + params="$params $@" + break + ;; + *) + params="$params $1" + shift + ;; + esac +done + +eval set -- "$params" + +retry () { + local -r -i max_attempts="$1"; shift + local -r cmd="$@" + local -i attempt_num=1 + + until $cmd + do + attempt_str="$attempt_num/$max_attempts" + if [ "$forever" = true ]; + then + attempt_str="$attempt_num" + fi + if (( attempt_num == max_attempts )) && [ "$forever" != true ]; + then + echo "Attempt $attempt_str failed. Giving up." + return 1 + else + echo "Attempt $attempt_str failed. Retrying in $sleep_duration seconds..." + ((attempt_num++)) + sleep "$sleep_duration" + fi + done +} + +retry "$num_attempts" "$@"