Skip to content

Instantly share code, notes, and snippets.

@iainlane
Last active December 12, 2022 10:45
Show Gist options
  • Save iainlane/78c5361bc41cc2ced2256cc8eaaf699a to your computer and use it in GitHub Desktop.
Save iainlane/78c5361bc41cc2ced2256cc8eaaf699a to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# Usage: retry <num-retries> <command> [arguments]
function retry {
local retries=$1
shift
local cmd=("$@")
case "${retries}" in
'' | *[!0-9]*)
echo "retries parameter must be a number greater than 0" >&2
return 1
;;
*)
if [ "${retries}" -le 0 ]; then
echo "retries parameter must be a number greater than 0" >&2
return 1
fi
;;
esac
local delay=1
local max_delay=60
local remaining_tries="${retries}"
# Try to run the command until it succeeds or we run out of retries
while true; do
# Check if set -e is set. If it is, toggle it off while running
# the command, so we don't just exit straight away.
if [[ "$-" =~ e ]]; then
set +e
eval "${cmd[*]}"
local exit_code=$?
set -e
else
# Set -e is not set, just run the command
eval "${cmd[*]}"
local exit_code=$?
fi
if [ "${exit_code}" -eq 0 ]; then
return 0
fi
if [ "${remaining_tries}" -eq 0 ]; then
# Return the exit code of the command
echo "Command failed, giving up after $((retries + 1)) attempts..." >&2
return ${exit_code}
fi
# Calculate the delay for the next iteration
delay=$((delay * 2))
if [ "${delay}" -gt "${max_delay}" ]; then
delay=${max_delay}
fi
echo "Command failed, retrying in ${delay} seconds..." >&2
sleep ${delay}
remaining_tries=$((remaining_tries - 1))
done
}
set -e
FOO=$(retry 2 false)
echo "${FOO}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment