基础概念与结构
crontab 是 Linux 系统内置的定时任务管理工具,通过预定义时间规则周期性执行命令或脚本。其时间规则由 5 个字段组成,格式为:
[分钟] [小时] [日期] [月份] [星期] [执行命令]
各字段取值范围:
- 分钟(0-59)
- 小时(0-23)
- 日期(1-31)
- 月份(1-12 或英文缩写)
- 星期(0-7,0 和 7 均表示周日)
操作命令
编辑任务列表
1
2
|
crontab -e # 编辑当前用户的任务
crontab -u username -e # 编辑指定用户的任务(需权限)
|
查看任务列表
1
2
|
crontab -l # 查看当前用户任务
crontab -u username -l # 查看指定用户任务
|
文件存储位置
- 用户级任务:
/var/spool/cron/(RHEL/CentOS)或 /var/spool/cron/crontabs/(Debian/Ubuntu)
- 系统级任务:
/etc/crontab 和 /etc/cron.d/ 目录
时间规则语法
| 特殊符号 |
说明 |
示例 |
说明 |
| * |
任意值 |
0 * * * * |
每小时整点执行 |
| , |
0 5,17 * * * |
0 5,17 * * * |
每天5点和17点执行 |
| - |
时间范围 |
0 0-6 * * * |
每天0-6点整点执行 |
| /n |
间隔频率 |
*/10 * * * * |
每10分钟执行 |
典型应用场景
固定时间执行
1
2
3
4
5
6
7
|
* * * * * /bin/sh /script.sh # 每分钟执行一次任务
0 2 * * * /bin/sh /script.sh # 每天02:00执行一次任务
0 17 * * sun /bin/sh /script.sh # 每周日 17:00 执行一次任务
*/10 * * * * /bin/sh /script.sh # 每 10min 执行一次任务
|
高频任务实现
每30秒执行一次任务的需求,因为crontab最小的是1 min。但是我们可以通过如下方法使用两条任务完成。
1
2
3
|
# 每30秒执行(通过sleep分段)
* * * * * /bin/sh /script.sh
* * * * * sleep 30; /bin/sh /script.sh
|
复合时间条件
1
2
3
4
5
6
7
8
|
# 每周五、周日17点执行任务
0 17 * * 5,7 /bin/sh /script.sh
# 每周五、周日4点、17点执行任务
0 4,17 * * 5,7 /bin/sh /script.sh
# 每年 1 月、5 月、8 月 的 每天 每小时每分钟 执行任务
* * * jan,may,aug * /bin/sh /script.sh
|
条件判断
1
2
|
# 每月的第一个周日2:00执行任务
0 2 * * sun [ $(date +%d) -le 07 ] && /bin/sh /script.sh
|
- 时间规则分解
- 时间表达式:0 2 * * sun
- 含义: 每周日(星期天)的凌晨 2:00 触发任务。
- 条件判断逻辑
- 命令部分: [ $(date +%d) -le 07 ] && /bin/sh /script.sh
- $(date +%d): 获取当前日期的「日」字段(例如:03 表示 3 日)。
- -le 07: 判断日期是否 ≤ 7(即每月前 7 天)。
- 整体逻辑:
- 当且仅当触发时间满足以下两个条件时,执行 /script.sh :
- 当前是 每周日的凌晨 2:00
- 当前日期在 每月的前 7 天 内(例如:3 月 5 日、6 月 1 日等)。
- 典型应用场景
- 月度首周任务
- 例如:每月第一个周日的凌晨执行数据归档(确保任务落在月初)。
- 跨周期校验
- 若任务需同时满足周频率和月周期(如每月前 7 天生成周报)。
系统级任务
1
|
0 4 * * * root /bin/bash restart_service.sh # 系统级任务需指定用户
|
高级技巧
crontab 提供的特殊时间宏(语法糖),用于简化任务的配置
1
|
@yearly /bin/bash /scripts.sh # 每年 1 月 1 日 00:00(午夜)执行一次任务
|
@yearly 仅精确到“年”,若需其他年度时间点(如每年 6 月 1 日),仍需使用标准表达式 0 0 1 6 *
同类语法糖
| 宏命令 |
等效表达式 |
说明 |
| @yearly |
0 0 1 1 * |
每年 1 月 1 日 00:00 执行 |
| @monthly |
0 0 1 * * |
每月 1 日 00:00 执行 |
| @daily |
0 0 * * * |
每天 00:00 执行 |
| @hourly |
0 * * * * |
每小时整点执行 |
| @reboot |
无等效表达式 |
系统启动时执行 |
示例参考
1
2
3
4
5
|
# 用户级任务:每年清理一次临时文件
@yearly find /tmp -type f -mtime +365 -delete
# 系统级任务:每年生成年度报告(需 root 权限)
@yearly root /opt/reports/generate_annual_report.sh
|
配置注意事项
环境变量问题
crontab 默认使用简化环境变量,建议脚本中使用绝对路径,或在任务中声明 PATH
日志与调试
- 任务执行记录:
/var/log/cron
- 输出重定向:
0 * * * * /script.sh > /log.txt 2>&1
服务管理
1
|
systemctl restart crond # 修改系统级配置后需重启服务
|
任务备份与恢复
1
2
|
crontab -l > cron_backup.txt # 备份
crontab cron_backup.txt # 恢复
|
其他问题
Permission denied
1
2
|
0 1 * * 1 /bin/sh /root/work_dir/docker-single/mysql/backupmysql_table.sh
0 0 * * * /bin/sh /root/docker/rustdesk/restart.sh
|
日志提示:
1
2
|
Dec 10 00:00:01 lavm-7zks6n0nja CROND[1832882]: (root) CMD (/root/docker/rustdesk/restart.sh)
Dec 10 00:00:01 lavm-7zks6n0nja CROND[1832866]: (root) CMDOUT (/bin/sh: /root/docker/rustdesk/restart.sh: Permission denied)
|
由于普通用户权限不足,无法运行shell脚本,需要使用 /bin/sh /xxxx/xxxx.sh 命令创建定时任务, 即在刚才指定脚本文件路径前面加上/bin/sh
docker-compose: command not found
sh脚本里面需要运行的命令不存在: docker-compose: command not found
crontab 环境变量不包含 /usr/local/bin,需显式添加路径或修改 PATH
修改脚本在脚本开头添加 docker-compose 的完整路径:
1
2
|
#!/bin/bash
/usr/local/bin/docker-compose restart # 替换为实际路径
|