aboutsummaryrefslogtreecommitdiff
path: root/bin/try.mi5
diff options
context:
space:
mode:
Diffstat (limited to 'bin/try.mi5')
-rw-r--r--bin/try.mi565
1 files changed, 65 insertions, 0 deletions
diff --git a/bin/try.mi5 b/bin/try.mi5
new file mode 100644
index 00000000..ea39d717
--- /dev/null
+++ b/bin/try.mi5
@@ -0,0 +1,65 @@
+# Attempt a certain number of times to perform a task, buffer stderr unless and
+# until all command attempts fail
+self=try
+
+# Parse options
+while getopts 's:n:' opt ; do
+ case $opt in
+ n)
+ attn=$OPTARG
+ ;;
+ s)
+ sleep=$OPTARG
+ ;;
+ \?)
+ printf >&2 '%s: Unknown option\n' "$self"
+ exit 2
+ ;;
+ esac
+done
+shift "$((OPTIND-1))"
+
+# Check we have at least one argument left (the command to run)
+if [ "$#" -eq 0 ] ; then
+ printf >&2 '%s: Need a command to run\n' "$self"
+ exit 2
+fi
+
+<%
+include(`include/mktd.m4')
+%>
+
+# Open a filehandle to the error buffer, just to save on file operations
+errbuff=$td/errbuff
+exec 3>"$errbuff"
+
+# Keep trying the command, writing error output to the buffer file, and exit
+# if we succeed on any of them
+attc=1
+: "${attn:=3}" "${sleep:=0}"
+while [ "$attc" -le "$attn" ] ; do
+
+ # Try running the command; if it succeeds, we're done, and any previous
+ # failures get their errors discarded
+ if "$@" 2>&3 ; then
+ exit
+
+ # If the command failed, record the exit value
+ else
+ ex=$?
+ fi
+
+ # If this isn't the last run, have a sleep
+ if [ "$attc" -lt "$attn" ] ; then
+ sleep "${sleep:=0}"
+ fi
+
+ # Increment the attempt count
+ attc=$((attc + 1))
+done
+
+# Attempts were exhausted, and all failed; print the error output from all of
+# the failures and exit with the non-zero exit value of the most recent one
+exec 3>&-
+cat -- "$td"/errbuff >&2
+exit "$ex"