Date:        Fri, 26 Feb 2021 16:42:37 +1100
    From:        Simon Burge <sim...@netbsd.org>
    Message-ID:  <20210226054237.6b07d4e...@thoreau.thistledown.com.au>

  | Thinking about adding this to our existing sleep(1), so anything
  | in existing libraries that makes this (much!) easier is welcome.

I use the following sh function as my sleep command, it does what
I need, and the advantage of being a function, rather than compiled
code, is that it is trivial to change if what it does isn't quite what
someone else needs.   It uses "date -d" (and so, parsedate(3)) for its
input parsing, and can be used as a conventional sleep command (simply
exec's sleep) or as "sleep until sometime+date+offset" where the latter
is whatever parsedate allows (as 1 or more args to the function).

kre

sleep()
{
        case "$1" in
        until)  ;;
        *)      command sleep "$@"; return;;
        esac

        shift
        case "$#" in
        0)      printf >&2 '%s\n' "Usage: sleep until date+time"; return 1;;
        esac

        local NOW=$(date +%s)
        local THEN; THEN=$(date -d "$*" +%s) || return 1
        local DELAY=$(( THEN - NOW ))
        case ${DELAY} in
        -*)     local HN=$(date -r "${NOW}" +%H)
                local HT=$(date -r "${THEN}" +%H)
                if [ "${HN#0}" -ge 14 ] && [ "${HT#0}" -le 6 ]
                then
                        THEN=$(date -d "$* tomorrow" +%s) || return 1
                        DELAY=$(( THEN - NOW ))
                fi
        esac
        case ${DELAY} in
        -*)     printf >&2 '%s\n' "In the past: $*"; return 1;;
        0)      return 0;;
        *)      command sleep "${DELAY}";;
        esac
}


Reply via email to