95 lines
2.6 KiB
Bash
Executable File
95 lines
2.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
cmd=""
|
|
timeoutSeconds=60
|
|
sleepSeconds=1
|
|
message=""
|
|
messageInterval=5
|
|
startTimeSeconds=$(date +%s)
|
|
elapsedSeconds=0
|
|
attempts=0
|
|
|
|
print_usage() {
|
|
echo "Usage: $0 [options] <command>"
|
|
echo
|
|
echo "Attempts to execute a given command periodically until it succeeds or a timeout occurs."
|
|
echo
|
|
echo "Options:"
|
|
echo " -t, --timeout The maximum number of seconds to wait for the command to succeed (default: 60)"
|
|
echo " -s, --sleep The number of seconds to sleep for between command attempts (default: 1)"
|
|
echo " -m, --message The progress message to print after every attempt (default: '')"
|
|
echo " Instances of {{elapsed}} and {{attempts}} in the message will be replaced by total"
|
|
echo " elapsed time (in seconds) and total attempts respectively."
|
|
echo " -i, --message-interval The number of command attempts to make before each printing of the progress message"
|
|
echo " (default: 5)."
|
|
echo " -e, --exit-command Optional command to run before exiting (default: '')"
|
|
echo
|
|
}
|
|
|
|
print_progress() {
|
|
if [ -n "$message" ]; then
|
|
echo "$message" | sed "s/{{attempts}}/$attempts/g; s/{{elapsed}}/$elapsedSeconds/g"
|
|
fi
|
|
}
|
|
|
|
# Parse options and arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-t | --timeout)
|
|
shift
|
|
timeoutSeconds="$1"
|
|
;;
|
|
-s | --sleep)
|
|
shift
|
|
sleepSeconds="$1"
|
|
;;
|
|
-m | --message)
|
|
shift
|
|
message="$1"
|
|
;;
|
|
-i | --message-interval)
|
|
shift
|
|
messageInterval="$1"
|
|
;;
|
|
-e | --exit-command)
|
|
shift
|
|
exitCommand="$1"
|
|
;;
|
|
*)
|
|
cmd="$@"
|
|
break
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# Error if no command was provided
|
|
if [ -z "$cmd" ]; then
|
|
print_usage
|
|
exit 1
|
|
fi
|
|
|
|
# Loop until either the command succeeds or a timeout occurs.
|
|
until [ "$elapsedSeconds" -gt "$timeoutSeconds" ] || eval "$cmd"; do
|
|
sleep "$sleepSeconds"
|
|
|
|
# Increment attempt counter. If we've hit the message interval, print the message
|
|
attempts=$((attempts + 1))
|
|
if [ $((attempts % messageInterval)) -eq 0 ]; then
|
|
print_progress
|
|
fi
|
|
|
|
# Recalculate $elapsedSeconds
|
|
currentTimeSeconds=$(date +%s)
|
|
elapsedSeconds=$((currentTimeSeconds - startTimeSeconds))
|
|
done
|
|
|
|
# If we timed out, print the final progress message and exit with code 1.
|
|
if [ "$elapsedSeconds" -gt "$timeoutSeconds" ]; then
|
|
print_progress
|
|
if [ -n "$exitCommand" ]; then
|
|
eval "$exitCommand"
|
|
fi
|
|
exit 1
|
|
fi
|