Есть ли инструмент командной строки, который просто оценит выражение cron и вернет ответ типа bool, если он должен работать прямо сейчас? Я ищу что-нибудь, что можно использовать в качестве утилиты в другом сценарии bash. Примерно так:
run_script=$(/tools/evaluate-cron-expression "02 4 * * *")
if [ "$run_script" -eq "1" ] # etc etc
Я знаю, я могу просто настроить реальное задание cron, но я играю с идеей обернуть все мои запланированные сценарии в другой сценарий.
Вы можете найти класс, который занимается этим здесь: http://www.phpclasses.org/package/641-PHP-Compares-timestamps-with-crontab-style-specifiers.html
Я использую этот класс около 7 лет. Он работал безупречно.
версия python из идеи php, спасибо!
import datetime
VALID_RANGES = {
'min': '0-59',
'hour': '0-23',
'day': '1-31',
'mon': '1-12',
'week': '0-6',
}
def is_cron_time(sc: str, time_now: datetime.datetime = datetime.datetime.now()) -> bool:
cron_l = sc.split(' ')
if not len(cron_l) == 5:
return False
cron_d = {
'min': cron_l[0],
'hour': cron_l[1],
'day': cron_l[2],
'mon': cron_l[3],
'week': cron_l[4]
}
time_now_d = {
'min': time_now.minute,
'hour': time_now.hour,
'day': time_now.day,
'mon': time_now.month,
'week': time_now.weekday()
}
for part, val in cron_d.items():
if val == '*':
continue
values = []
"""For patters like 0-23/2"""
if '/' in val:
rng, steps = val.split('/')
if rng == '*':
rng = VALID_RANGES[part]
start, stop = [int(s) for s in rng.split('-')]
values = list(range(start, stop, int(steps)))
else:
"""For patters like :
2
2,5,8
2-23
"""
for v in val.split(','):
if v == '*':
# should never happen
break
if '-' in v:
start, stop = [int(s) for s in v.split('-')]
values = list(range(int(start), int(stop)))
else:
values.append(int(v))
if time_now_d[part] not in values:
return False
return True
def test():
DT = datetime.datetime
_now = DT.now()
tests = [
{'cron': '* * * * *', 'dt': _now, 'ass': True},
{'cron': '0 * * * *', 'dt': DT(_now.year, _now.month, _now.day, _now.hour, 0), 'ass': True},
{'cron': '2 * * * *', 'dt': DT(_now.year, _now.month, _now.day, _now.hour, 10), 'ass': False},
{'cron': '*/2 * * * *', 'dt': DT(_now.year, _now.month, _now.day, _now.hour, 10), 'ass': True},
{'cron': '2-15 * * * *', 'dt': DT(_now.year, _now.month, _now.day, _now.hour, 10), 'ass': True},
]
for cron, dt, ass in [t.values() for t in tests]:
assert is_cron_time(cron, dt) is ass, f'{cron} fail on {dt}'
test()