Skip to content

Instantly share code, notes, and snippets.

@WimObiwan
Last active November 27, 2015 10:19
Show Gist options
  • Save WimObiwan/03bceb2481e45cb172f9 to your computer and use it in GitHub Desktop.
Save WimObiwan/03bceb2481e45cb172f9 to your computer and use it in GitHub Desktop.
cron-test.sh: tests if a date/time (or the current time if no time) matches a cron specifier. Only the *standard* special characters are supported:
#!/bin/bash
target=$1
datetime=$2
if [ -z "$target" ] ; then
>&2 echo 'No target is specified.'
>&2 echo "Usage: $0 <cron-specification> [<date-time>]"
>&2 echo " e.g. $0 '* 16,17 * * *'"
>&2 echo " e.g. $0 '* 16,17 * * *' '2014-01-01 17:32'"
>&2 echo "Crontab syntax: Minute Hour DayOfMonth Month DayOfWeek"
>&2 echo "Only the basic syntax is supported. This includes multiple values (16,17),"
>&2 echo " ranges (13-17) and predefined schedules (@daily,...)"
>&2 echo "All other things (like multiple values combined with ranges) are NOT"
>&2 echo " supported."
exit 2
fi
if [ -z "$datetime" ] ; then
components=$(date +"%M %H %d %m %w")
else
components=$(date --date "$datetime" +"%M %H %d %m %w")
fi
case $target in
@yearly )
target='0 0 1 1 *' ;;
@annually )
target='0 0 1 1 *' ;;
@monthly )
target='0 0 1 * *' ;;
@weekly )
target='0 0 * * 0' ;;
@daily )
target='0 0 * * *' ;;
@midnight )
target='0 0 * * *' ;;
@hourly )
target='0 * * * *' ;;
esac
if [ $(echo "$target" | wc -w) -ne "5" ]
then
>&2 echo "Invalid target specification: $target"
exit 2
fi
if [ $(echo "$components" | wc -w) -ne "5" ]
then
>&2 echo "Invalid component list: $component"
exit 2
fi
for i in 1 2 3 4 5
do
t=$(echo "$target" | awk -v N=$i '{print $N}')
c=$(echo "$components" | awk -v N=$i '{print $N}')
#>&2 echo "Checking $t - $c"
# star match
if [ "$t" = '*' ] ; then
#>&2 echo "Checking $t - $c ==> STAR MATCH"
continue
fi
# interval match
if [[ "$t" =~ ^([^-]+)-([^-]+)$ ]] ; then
from="${BASH_REMATCH[1]}"
to="${BASH_REMATCH[2]}"
if [ $from -le $c -a $c -le $to ] ; then
#>&2 echo "Checking $t - $c ==> INTERVAL [$from,$to] MATCH"
continue
else
#>&2 echo "Checking $t - $c ==> INTERVAL [$from,$to] NO MATCH"
exit 1
fi
fi
# comma separated list
if [[ "$t" =~ , ]] ; then
IFS=","
found=0
for i in $t
do
if [ "$c" = "$i" ] ; then
found=1
break
fi
done
if [ $found -eq 1 ] ; then
#>&2 echo "Checking $t - $c ==> LIST [$t] MATCH"
continue
else
#>&2 echo "Checking $t - $c ==> LIST [$t] NO MATCH"
exit 1
fi
fi
# exact match
if [ "$c" = "$t" ] ; then
#>&2 echo "Checking $t - $c ==> EXACT MATCH"
continue
fi
#>&2 echo "Checking $t - $c ==> NO MATCH"
exit 1
done
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment