6月21日 21:41

Linux cron 时间格式怎么写?常用命令和最佳实践有哪些?

cron 是什么,适合解决什么问题?

cron 是 Linux/Unix 系统里最常见的定时任务工具,适合做周期性、可重复、对秒级精度要求不高的任务,比如清理日志、备份文件、同步数据、定时拉取接口、跑统计脚本。

它的特点是简单、稳定、系统内置;缺点是默认环境变量很少、日志不集中、任务错过后通常不会自动补跑。所以写 cron 任务时,不只要会写时间表达式,还要处理路径、日志、锁、时区和失败通知。

cron 时间格式怎么写?

普通用户的 crontab 通常是 5 个时间字段加一条命令:

bash
* * * * * command # 分 时 日 月 周 命令

常见例子:

bash
30 2 * * * /usr/local/bin/backup.sh # 每天 2:30 */5 * * * * /usr/local/bin/check.sh # 每 5 分钟 0 9 * * 1 /usr/local/bin/weekly-report.sh # 每周一 9 点

常用符号包括:* 任意值,, 多个值,- 范围,/ 步长。

日期和星期同时写时有什么坑?

在很多 cron 实现里,日期字段 day-of-month 和星期字段 day-of-week 如果同时被限制,通常是“或”的关系,不是“且”的关系”。

bash
0 9 1 * 1 /usr/local/bin/job.sh

很多人以为它表示“每月 1 号且是周一的 9 点执行”。实际上通常表示每月 1 号 9 点执行,周一 9 点也执行。如果真的要表达“每月 1 号并且是周一”,建议在脚本里再判断一次。

crontab 常用命令有哪些?

bash
crontab -e # 编辑当前用户任务 crontab -l # 查看当前用户任务 crontab -r # 删除当前用户所有任务 sudo crontab -u nginx -e sudo crontab -u nginx -l

编辑前建议先备份:

bash
crontab -l > ~/crontab.bak

用户 crontab 的格式是 * * * * * command/etc/crontab/etc/cron.d/ 里的格式通常多一个运行用户字段:* * * * * user command。不要混用。

cron 的环境变量为什么经常出问题?

cron 执行命令时,不会加载完整交互式 shell 环境。建议在 crontab 顶部显式写清楚:

bash
SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin MAILTO=admin@example.com

命令和脚本尽量用绝对路径,需要进入项目目录时显式 cd

bash
*/10 * * * * cd /data/app && /usr/bin/python3 scripts/sync.py >> /var/log/sync.log 2>&1

日志和防重入怎么做?

cron 自身日志位置和发行版有关:Debian/Ubuntu 常见 grep CRON /var/log/syslog,RHEL/CentOS 常见 grep CRON /var/log/cron,systemd 系统也可以看 journalctl -u cronjournalctl -u crond

生产环境建议自己重定向日志:

bash
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

如果任务执行时间比调度间隔还长,会出现多个实例同时运行。最简单可靠的办法是用 flock 加锁:

bash
*/5 * * * * flock -n /var/lock/sync.lock /usr/local/bin/sync.sh >> /var/log/sync.log 2>&1

cron 和时区有什么关系?

cron 按系统时区执行。先确认服务器时区:

bash
date timedatectl

部分 cron 实现支持在 crontab 中设置 CRON_TZ

bash
CRON_TZ=Asia/Shanghai 0 9 * * * /usr/local/bin/report.sh

跨地区部署时,最好把服务器时区、业务时区和任务说明写清楚。对账、结算、计费这类任务,还要做幂等和日期校验,不要只相信 cron 调度。

anacron 和 systemd timer 怎么选?

cron 假设机器一直开着。如果电脑或服务器在计划时间关机,任务通常就错过了。anacron 适合每天、每周、每月这类低频任务,错过后下次开机补跑。

systemd timer 更适合生产服务化任务,它日志进 journald,可声明用户、工作目录、依赖和错过补跑。一个 timer 通常由 .service.timer 两个文件组成。

ini
# /etc/systemd/system/report.timer [Timer] OnCalendar=*-*-* 02:30:00 Persistent=true

启用:

bash
sudo systemctl daemon-reload sudo systemctl enable --now report.timer systemctl list-timers journalctl -u report.service

简单任务用 cron,生产任务需要状态、日志、依赖、告警时优先考虑 systemd timer。

cron 最佳实践清单

使用绝对路径;显式设置 SHELLPATH;保存日志;用 flock 防重入;脚本要幂等;区分用户 crontab 和系统 cron;注意日期和星期字段的“或”关系;确认时区;复杂逻辑写进脚本;关键任务配置告警。

cron 本身不复杂,真正让任务稳定的是这些细节:命令能不能找到,失败能不能看见,重复执行会不会出事,时间是不是你以为的那个时间。

标签:Linux