Skip to content

Instantly share code, notes, and snippets.

@RobinKnipe
Last active May 9, 2023 07:06
Show Gist options
  • Select an option

  • Save RobinKnipe/b8c624086bef36d4f7044cbf39e30e08 to your computer and use it in GitHub Desktop.

Select an option

Save RobinKnipe/b8c624086bef36d4f7044cbf39e30e08 to your computer and use it in GitHub Desktop.
Repeat until error

Repeat until error

A simple "Ronseal" function, that repeats a specified command until it fails with an error - i.e. returns a non-zero return code.

Usage

I like to create an alias for the function (in ~/.bash_aliases, or simmilar), i.e.

source rue.sh
alias rue='repeatUntilError'

Then you can use the function, and get help more easily:

$ rue

repeatUntilError [ OPTIONS... ] -- CMD
  Runs the CMD and checks it completed successfully before running it again, otherwise exits.
OPTIONS:
  -h print this help message and exit
  -n <message> send a system notification to alert the user the loop has finished
  -s [file] play a sound when the loop has finished, optionally specify a sound file
  -- tells the program there are no more options, all further args are the CMD to run
EXAMPLE:
  $ repeatUntilError -s -n 'Random "a" found' -- 'grep -v a <( head -c 8 /dev/urandom )'
  this will search random 8 character strings until 'a' is found, then stop and notify

Example

I use it to restart a short-lived DB tunnel:

repeatUntilError -s -n 'DB tunnel collapsed' -- \
  kubectl --context=foo port-forward postgres-proxy 5432

This way I don't have to keep doing it manually, the function reruns the tunnel command after the connection closes. When the command finally fails, it plays a sound and sends an alert displayd by the standard OS notification process.

Dependencies

The script uses the following utilities:

  • notify-send, for the OS notifications (text)
  • cvlc, a part of the vlc installation, for playing sounds
#!/bin/bash
function repeatUntilError {
local help="
repeatUntilError [ OPTIONS... ] -- CMD
Runs the CMD and checks it completed successfully before running it again, otherwise exits.
OPTIONS:
-h print this help message and exit
-n <message> send a system notification to alert the user the loop has finished
-s [file] play a sound when the loop has finished, optionally specify a sound file
-- tells the program there are no more options, all further args are the CMD to run
EXAMPLE:
$ repeatUntilError -s -n 'Random \"a\" found' -- 'grep -v a <( head -c 8 /dev/urandom )'
this will search random 8 character strings until 'a' is found, then stop and notify
"
while [[ "$1" =~ ^-.* ]]
do
case "$1" in
"--" ) shift ; break ;;
"-n" ) local alert_notify="$2" ; shift ; shift ;;
"-s" )
local alert_sound='/usr/share/sounds/freedesktop/stereo/service-logout.oga'
if ! [[ "$2" =~ ^-.* ]] ; then
local alert_sound="$2"
shift
fi
shift ;;
"-h" ) printf "${help}" ; return ;;
* ) printf "Unrecognised option: $1\n${help}" ; return ;;
esac
done
if [ $# -eq 0 ]
then
printf "${help}"
return
fi
local cmd="$@"
while :
do
echo "$cmd"
bash -c -- "$cmd"
if [ $? -ne 0 ]
then
[ -n "${alert_notify}" ] && notify-send "${alert_notify}"
[ -n "${alert_sound}" ] && [ -e "`which cvlc`" ] && cvlc --play-and-exit "${alert_sound}" &> /dev/null
break
fi
done
}
# if script called directly, run the function
[ $# -ne 0 ] && repeatUntilError "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment