![评估 cron 表达式](https://linux22.com/image/600192/%E8%AF%84%E4%BC%B0%20cron%20%E8%A1%A8%E8%BE%BE%E5%BC%8F.png)
是否有一个命令行工具可以简单地评估 cron 表达式并返回布尔响应(如果它现在应该正在运行)?我正在寻找可以用作另一个 bash 脚本中的实用程序的东西。像这样:
run_script=$(/tools/evaluate-cron-expression "02 4 * * *")
if [ "$run_script" -eq "1" ] # etc etc
我知道,我知道,我可以设置一个真正的 cron 作业,但我正在考虑将所有计划的脚本包装在另一个脚本中。
答案1
您可以在这里找到处理此问题的课程:http://www.phpclasses.org/package/641-PHP-Compares-timestamps-with-crontab-style-specifiers.html
我已经使用这个课程大约 7 年了。它运行完美。
答案2
来自 php idea 的 python 版本,谢谢!
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()