The normal cron
doesn't give you that level of expressiveness but there's nothing stopping you from putting further restrictions in the command portion of the entry:
*/3 8-15 * * * [[ 1$(date +\%H\%M) -ge 10830 ]] && [[ 1$(date +\%H\%M) -le 11515 ]] && payload
This will actually run the cron
job itself every three minutes between 8am and 4pm, but the payload (your script that does the actual work) will only be called if the current time is between 8:30am and 3:15pm.
The placing of 1
in front of the time is simply a trick to avoid issues treating numbers starting with zero as octal.
In fact, I have a script withinTime.sh
that proves useful for this sort of thing:
usage() {
[[ -n "$1" ]] && echo "$1"
echo "Usage: withinTime <hhmmStart> <hhmmEnd>"
}
validTime() {
[[ "$1" =~ ^[0-9]{4}$ ]] || return 1 # Ensure 0000-9999.
[[ $1 -le 2359 ]] || return 1 # Ensure 0000-2359.
return 0
}
# Parameter checking.
[[ $# -ne 2 ]] && { usage "ERROR: Not enough parameters"; exit 1; }
validTime "$1" || { usage "ERROR: invalid hhmmStart '$1'"; exit 1; }
validTime "$2" || { usage "ERROR: invalid hhmmEnd '$2'"; exit 1; }
now="1$(date +%H%M)"
[[ ${now} -lt 1${1} ]] && exit 1 # If before start.
[[ ${now} -gt 1${2} ]] && exit 1 # If after end.
# Within range, flag okay.
exit 0
With this script in your path, you can simplify the cron
command a little:
*/3 8-15 * * * /home/pax/bin/withinTime.sh 0830 1515 && payload