crontab 报 bad minute 错误怎么解决?
bad minute 表示某行的分钟字段(第一列)不是合法表达式:按报错行号检查拼写、意外换行、全角字符与非法值。本文列出各类触发原因与排查方法。
含义:cron 逐行解析 crontab,凡不是注释(#开头)也不是环境变量(KEY=VALUE)的行,都必须是合法的"分钟 小时 日 月 周 命令"格式;第一列(分钟)解析失败就报 bad minute。报错信息里带行号,照着行号查即可。
排查步骤
报错形如:
"/tmp/crontab.gLfS38":4: bad minute
第 4 行有问题。常见病因对照:
病因一:拼写错误/非法值
60 * * * * /job.sh # ❌ 分钟范围是 0-59,60 非法
*/0 * * * * /job.sh # ❌ 步长为 0 无意义
病因二:意外换行(最常见)
0 0 * * *
/command/to/execute # ❌ 命令被挤到下一行,该行以 / 开头,第一列解析失败
一条任务必须写在一行里。
病因三:全角字符混入
从文档/微信复制过来的配置常带全角空格、全角星号(*)——肉眼难辨,cron 不认。重写该行或用 cat -A 现形:
crontab -l | cat -A | sed -n '4p'
# 全角字符会显示成 M-xxx 乱码样
病因四:注释没加
每天凌晨备份 # ❌ 中文说明没注释符,被当任务行解析
0 0 * * * /backup.sh # ✅ 注释单独一行或符合规范
稳妥做法:注释单独一行并以 # 开头。
病因五:特殊宏拼错
@dailyy /job.sh # ❌ 拼错;正确:@daily @hourly @reboot @weekly @monthly @yearly
写完先验证
crontab -l # 看当前生效内容
# 或把文件喂给 cron 做语法检查
crontab -T /path/to/file 2>/dev/null || crontab /path/to/file -u testuser --dry-run 2>/dev/null
最稳妥:crontab -e 编辑保存时 cron 会自动校验并提示错误行。
观测云对照
配置错误导致任务不跑,监控兜底。 crontab 静默失效的场景(改错了但当时没发现)靠观测云的心跳告警发现:预期周期没产生任务日志即通知。
常见问题(FAQ)
*Q:分钟位写 * 和 /1 有区别吗?
A:效果相同(每分钟),写 * 即可。
Q:报错行号和我数的不一样?
A:crontab -e 编辑的是临时文件,行号含文件头部可能有的注释行;直接打开报错中显示的临时文件路径看最准。
Q:秒级调度怎么写?
A:cron 最小粒度是分钟;秒级用 systemd timer(OnUnitActiveSec)或应用内调度器。