Skip to content

Instantly share code, notes, and snippets.

@t-takata
Last active April 15, 2020 09:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t-takata/693702383560acde03064f681d494834 to your computer and use it in GitHub Desktop.
Save t-takata/693702383560acde03064f681d494834 to your computer and use it in GitHub Desktop.
Run command at specified time without at(1).
#!/bin/sh
EX_USAGE=64
EX_DATAERR=65
WAKEUP_BEFORE_S=10
BUSYLOOP_SLEEP_US=500000
usage_exit() {
echo "Usage: $0 [-xf] time command args..." 1>&2
echo " -x: debug mode" 1>&2
echo " -f: force exec" 1>&2
exit $EX_USAGE
}
exec_cmd() {
"$SHELL" -c "$*"
}
FORCE_EXEC=0
while getopts "dxfh?" OPT
do
case $OPT in
x)
set -x
: "Set debug mode."
;;
f)
: "Set force exec(if specified time is past time)"
FORCE_EXEC=1
;;
h) usage_exit
;;
\?) usage_exit
;;
esac
done
shift $((OPTIND - 1))
TIME_STR="$1"
shift
if echo "$TIME_STR" | grep -q '^+[0-9][0-9]*$'; then
TIME_STR="$(date -d "$TIME_STR minutes" +'%Y/%m/%d %H:%M:00')"
fi
TIME_UT=`date -d "${TIME_STR}" +"%s"`
NOW_UT=`date +"%s"`
TIME_DIFF=`expr "$TIME_UT" - "$NOW_UT"`
if [ "$TIME_DIFF" -lt 0 ]; then
if [ "$FORCE_EXEC" -ne 1 ]; then
: "Past time. exiting..."
exit $EX_DATAERR
fi
fi
: "Command will execute at `date -d @"$TIME_UT"`"
TIME_SLEEP=`expr "$TIME_DIFF" - "$WAKEUP_BEFORE_S"`
if [ "$TIME_DIFF" -gt 10 ]; then
sleep "$TIME_SLEEP"
fi
CURRENT_UT=`date +"%s"`
while [ "$CURRENT_UT" -lt "$TIME_UT" ]; do
usleep "$BUSYLOOP_SLEEP_US"
CURRENT_UT=`date +"%s"`
done
exec_cmd "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment