2021-07-29 05:44:12 -07:00
|
|
|
#!/usr/bin/env dash
|
2024-07-23 00:04:57 -07:00
|
|
|
# compat: +ash +bash +dash -hush -ksh +mksh +oksh +osh +posh +yash +zsh
|
2015-03-05 07:15:09 -08:00
|
|
|
|
2021-07-30 17:57:08 -07:00
|
|
|
minutemaid() { ### @-
|
2021-09-29 04:51:37 -07:00
|
|
|
### check if the current minute is divisible by a given number,
|
|
|
|
### and optionally execute a command if it is. if a command is given,
|
|
|
|
### either execute the command and return its exit value,
|
|
|
|
### or execute nothing and return 0. if a command is omitted,
|
|
|
|
### either return 0 on the minute, or return 1.
|
|
|
|
###
|
|
|
|
### note that a "minute" is relative to the seconds since the epoch,
|
|
|
|
### not the minute of the hour. this ensures that commands will run
|
|
|
|
### roughly every N minutes, regardless of the minute hand on the clock.
|
|
|
|
###
|
|
|
|
### note that `minutemaid 1` will always return 0,
|
|
|
|
### and `minutemaid 1 command` will always execute the command,
|
2021-09-29 05:03:06 -07:00
|
|
|
### since every integral interval is evenly divisible by 1.
|
|
|
|
### `minutemaid 0`, and any negative interval, is an error.
|
2021-07-30 17:57:08 -07:00
|
|
|
###
|
|
|
|
### ```
|
|
|
|
### # crontab usage:
|
|
|
|
### * * * * * minutemaid 9 ~/work/do_my_bidding # runs every nine minutes
|
2021-09-29 04:51:37 -07:00
|
|
|
### # loop usage:
|
|
|
|
### until minutemaid 9; do sleep 5; done
|
|
|
|
### echo the wait is finally over; date
|
|
|
|
### # improper usage:
|
|
|
|
### while minutemaid 1; do sleep 1; done
|
|
|
|
### echo this will never happen
|
2021-07-30 17:57:08 -07:00
|
|
|
### ```
|
|
|
|
|
2021-09-30 08:43:40 -07:00
|
|
|
local offset=0 name=
|
2021-07-29 05:44:12 -07:00
|
|
|
while getopts 'o:h' name; do
|
|
|
|
case $name in
|
2021-07-29 00:37:35 -07:00
|
|
|
o) offset="$OPTARG";;
|
2024-07-23 00:04:57 -07:00
|
|
|
?) local fd=0 # FIXME: this also matches single-character filenames!
|
2021-07-29 05:44:12 -07:00
|
|
|
[ $name = h ] && fd=1 || fd=2
|
2021-09-29 06:14:02 -07:00
|
|
|
printf '%s\n' "usage: $0 [-o offset] {interval} [{command} [{args...}]]" >&$fd
|
2021-07-29 05:44:12 -07:00
|
|
|
[ $name = h ] && return 0 || return 1;;
|
2021-07-29 00:37:35 -07:00
|
|
|
esac
|
|
|
|
done
|
|
|
|
shift $((OPTIND-1))
|
2015-03-05 06:49:03 -08:00
|
|
|
|
2021-07-29 00:37:35 -07:00
|
|
|
local interval="${1:?no interval specified}"
|
2015-03-05 07:15:09 -08:00
|
|
|
shift
|
|
|
|
|
2021-09-29 06:14:02 -07:00
|
|
|
if [ "$interval" -gt 0 ] 2>/dev/null; then
|
|
|
|
:
|
|
|
|
else
|
|
|
|
printf "%s\n" "$0: interval must be a positive integer" >&2
|
2021-09-29 05:03:06 -07:00
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
2021-07-29 00:37:35 -07:00
|
|
|
local sec="$(date +%s)"
|
2021-07-29 05:44:12 -07:00
|
|
|
local min="$((sec/60+offset))"
|
|
|
|
local mod="$((min%interval))"
|
2021-07-29 00:37:35 -07:00
|
|
|
if [ $# -gt 0 ]; then
|
2021-07-29 05:44:12 -07:00
|
|
|
[ $mod -ne 0 ] || "$@"
|
2021-07-29 00:37:35 -07:00
|
|
|
else
|
|
|
|
[ $mod -eq 0 ] && return 0 || return 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-08-02 13:48:46 -07:00
|
|
|
[ -n "${preload+-}" ] || minutemaid "$@"
|