Linux crontab 详解
1) crontab 是什么
cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。
常见两类:
用户 crontab:每个用户一份(
crontab -e编辑)系统级 crontab / cron.d:可指定执行用户(
/etc/crontab、/etc/cron.d/*)
2) crontab 时间格式(核心)
标准格式 5 个时间字段 + 1 个命令:
# ┌──────── 分钟(0-59) # │ ┌────── 小时(0-23) # │ │ ┌──── 日(1-31) # │ │ │ ┌── 月(1-12) # │ │ │ │ ┌─ 周(0-7,0/7都表示周日) # │ │ │ │ │ # * * * * * command
常用写法
*:任意值(每分钟/每小时/每天…)*/n:每 n 个单位一次
例:*/5 * * * *每 5 分钟a,b,c:列举
例:0 9,18 * * *每天 9 点和 18 点a-b:范围
例:0 9-18 * * *9~18 点整点a-b/n:范围内步进
例:0 9-18/2 * * *9~18 点每 2 小时一次
“日”和“周”同时指定的坑
在很多 cron 实现中(Vixie cron / cronie 常见规则):“日(DoM)”与“周(DoW)”如果都不是 *,通常是“或(OR)”关系
也就是满足其一就会触发。
例:0 9 1 * 1 往往表示:每月 1 号 9 点 以及 每周一 9 点(不是“每月1号且周一才跑”)。
3) 预定义特殊字符串(更易读)
有些 cron 支持(多数 Linux 支持):
@reboot # 开机后执行一次 @yearly # 每年 1 次(= 0 0 1 1 *) @monthly # 每月 1 次(= 0 0 1 * *) @weekly # 每周 1 次(= 0 0 * * 0) @daily # 每天 1 次(= 0 0 * * *) @hourly # 每小时 1 次(= 0 * * * *)
例:
@reboot /usr/local/bin/start_my_service.sh
4) 怎么编辑/查看/管理
编辑当前用户的定时任务
crontab -e
查看
crontab -l
删除全部
crontab -r
指定用户(需要 root)
crontab -u username -e crontab -u username -l
5) 系统级 crontab:/etc/crontab 与 /etc/cron.d
/etc/crontab 格式多了 “用户” 字段(第 6 列)
* * * * * user command
示例(每小时执行一次,root 身份):
0 * * * * root /usr/local/bin/job.sh
/etc/cron.d/* 也是同样格式,适合按应用拆分文件管理。
6) 输出、日志与环境变量(非常关键)
6.1 cron 的环境很“干净”
PATH可能很短(如/usr/bin:/bin)不会加载你的
.bashrc/.profile所以脚本里尽量使用绝对路径,或在 crontab 里显式设置 PATH
示例:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
6.2 重定向输出(否则可能邮件/丢失)
把 stdout/stderr 都写到日志:
*/5 * * * * /usr/local/bin/job.sh >> /var/log/job.log 2>&1
只要错误:
*/5 * * * * /usr/local/bin/job.sh > /dev/null 2>>/var/log/job.err
6.3 常用 crontab 变量
SHELL=/bin/bash PATH=... MAILTO=you@example.com # 不想发邮件可设为空:MAILTO=""
7) 常见示例(直接可用)
每天 02:30 执行
30 2 * * * /usr/local/bin/backup.sh
工作日(周一到周五)9:00 执行
0 9 * * 1-5 /usr/local/bin/report.sh
每 10 分钟执行
*/10 * * * * /usr/local/bin/healthcheck.sh
每月 1 日 00:05 执行
5 0 1 * * /usr/local/bin/monthly.sh
开机启动
@reboot /usr/local/bin/onboot.sh >> /var/log/onboot.log 2>&1
8) 服务状态与排错
cron 服务
不同发行版可能叫 cron 或 crond:
systemctl status cron systemctl status crond
启动/重启:
sudo systemctl restart cron # 或 crond
查看日志
Debian/Ubuntu:常见在
/var/log/syslog(搜索 CRON)CentOS/RHEL:常见在
/var/log/cron
例:
grep CRON /var/log/syslog# 或grep CRON /var/log/cron
常见踩坑
脚本没权限:
chmod +x /path/script.sh没写绝对路径:命令找不到
依赖环境变量/conda/java 等未加载:在脚本里显式
source或写完整路径时区:服务器时区与预期不一致(
timedatectl查看)并发:任务没跑完又启动一次(可用
flock防重入)
防重入示例:
* * * * * flock -n /tmp/job.lock /usr/local/bin/job.sh