Retry a Command Until It Succeeds or Times Out in Bash
Retry a command until it succeeds or a time limit passes by comparing the SECONDS variable inside an until loop. The function returns 1 and says so on timeout.
A job depends on something that comes up a little later, and you want to try again for a while and then give up with a clear failure.
retry() {
local limit=$1 start=$SECONDS
shift
until "$@"; do
if (( SECONDS - start >= limit )); then
echo "gave up after ${limit}s" >&2
return 1
fi
sleep 1
done
}
( sleep 3; touch ready ) &
retry 10 test -e ready && echo "succeeded after about ${SECONDS}s"
rm -f ready
retry 2 test -e ready
echo "exit status: $?"succeeded after about 3s
gave up after 2s
exit status: 1Bash increments SECONDS every second, so remembering its value at the start and comparing it to the current one gives an elapsed time without calling date. The loop runs the command with until, sleeps one second between attempts and returns 1 when the limit passes. In the run, the file appeared after three seconds and the first call reported success, while the second call, with a limit of 2, printed gave up after 2s and exit status 1. See Bash Variables.
The limit is checked only between attempts, so a command that hangs is never interrupted; wrap the attempt in timeout 5 cmd when that can happen. A fixed one-second delay is fine for a local service, and a remote one deserves a longer, growing delay.