#!/usr/bin/fish function retry -d 'Retry a command up to a specified number of times, until it exits successfully' if test (count $argv) -lt 2; or string match -irqv '^[0-9]+$' $argv[1] printf 'Proper use: %s [number of attempts until giving up] [command to attempt]\n' (status function); return 23 else set -l retries $argv[1] set -l command (string split -m 1 ' ' "$argv")[2]; and printf 'eval %s\n' (printf '%s ' $command) for i in (seq $retries) eval $command set -l cmd_status $status if test $cmd_status -eq 0 printf 'Try #%d of %d succeeded.\n' $i $retries return 0 else if test $i -eq $retries set -l exit $status printf 'Final try #%d exited %d.\n' $i $cmd_status return $cmd_status else set -l wait (math "2 ^ ($i - 1)") printf 'Try #%d of %d exited %d, retrying in %s...\n\n' $i $retries $cmd_status (math "1000 * $wait" | humanize_duration) sleep $wait end end end end