文章目录
Cron 最适合安排重复性任务。 可以使用关联的 at 实用程序来完成一次性任务的调度。
参考:
- Devhints (devhints.io)
- Crontab Generator (crontab-generator.org)
- Crontab guru (crontab.guru)
Crontab 格式
格式
Min Hour Day Mon Weekday
分钟 小时 天 月 周
* * * * * <要执行的命令>
┬ ┬ ┬ ┬ ┬
│ │ │ │ └─ 星期几 (0=周日 .. 6=星期六)
│ │ │ └────── 月 (1..12)
│ │ └─────────── 月份中的某天 (1..31)
│ └──────────────── 小时 (0..23)
└───────────────────── 分钟 (0..59)
字段 | 范围 | 特殊字符 |
---|---|---|
分钟 Minute | 0 - 59 | , - * / |
小时 Hour | 0 - 23 | , - * / |
月份中的某天 | 1 - 31 | , - * ? / L W |
月 Month | 1 - 12 | , - * / |
星期几 | 0 - 6 | , - * ? / L # |
年 Year | 1970–2099 | , - |
示例
Example | Description |
---|---|
*/15 * * * * | 每 15 分钟 |
0 * * * * | 每隔一小时 |
0 */2 * * * | 每 2 小时 |
15 2 * * * | 每天凌晨 2 点 15 分 |
15 2 * * ? | 每天凌晨 2 点 15 分 |
10 9 * * 5 | 每周五上午 9:10 |
0 0 * * 0 | 每个星期日的午夜 |
15 2 * * 1L | 每月最后一个星期一凌晨 2 点 15 分 |
15 0 * * 4#2 | 每个月的第二个星期四早上 00:15 |
0 0 0 1 * * | 每个月的 1 日(每月) |
0 0 0 1 1 * | 每年 1 月 1 日(每年) |
@reboot | 每次重启 (非标准) |
特殊字符串
特殊字符串 | 意义 |
---|---|
@reboot | 运行一次,在系统启动时 (非标准) |
@yearly | 每年运行一次,“0 0 1 1 *” (非标准) |
@annually | (与@yearly 相同)(非标准) |
@monthly | 每月运行一次,“0 0 1 * *” (非标准) |
@weekly | 每周运行一次,“0 0 * * 0” (非标准) |
@daily | 每天运行一次,“0 0 * * *” (非标准) |
@midnight | (与@daily 相同)(非标准) |
@hourly | 每小时运行一次,“0 * * * *” (非标准) |
Crontab 命令
- | - |
---|---|
crontab -e | 如果不存在,则编辑或创建一个 crontab 文件 |
crontab -l | 显示 crontab 文件 |
crontab -r | 删除 crontab 文件 |
crontab -v | 显示您上次编辑 crontab 文件的时间 (非标准) |
轻松添加任务
echo "@reboot echo hi" \| crontab
特殊字符
特殊字符 | 说明 |
---|---|
星号(*) | 匹配字段中的所有值或任何可能的值。 |
横杆(-) | 用于定义范围。例如:第 5 个字段(星期几)中的 1-5 每个工作日,即星期一到星期五 |
斜线 (/) | 第一个字段(分钟)/15 表示每十五分钟或范围的增量。 |
逗号(,) | 用于分隔项目。例如:第二个字段(小时)中的 2、6、8 在凌晨 2 点、早上 6 点和早上 8 点执行 |
L | 仅允许用于 月份中的某天 或 星期几 字段,星期几 中的 2L 表示每个月的最后一个星期二 |
井号 (#) | 仅允许用于 星期几 字段,后面必须在 1 到 5 的范围内。例如,4#1 表示给定月份的“第一个星期四”。 |
问号(?) | 可以代替“*”并允许用于月份和星期几。使用仅限于 cron 表达式中的 月份中的某天 或 星期几 。 |
Crontab 是 Linux/Unix 系统中用于设置周期性执行任务的工具,下面详细介绍如何使用 crontab 添加和管理定时任务。
1. 基本操作命令
查看当前用户的定时任务
crontab -l
编辑定时任务
crontab -e
删除所有定时任务
crontab -r
删除特定用户的定时任务(需要 root 权限)
crontab -r -u username
2. Crontab 时间格式
Crontab 时间格式由 5 个时间字段组成,格式如下:
* * * * * command_to_execute
│ │ │ │ │
│ │ │ │ └── 星期几 (0 - 6) (0 表示星期日)
│ │ │ └──── 月份 (1 - 12)
│ │ └────── 日 (1 - 31)
│ └──────── 小时 (0 - 23)
└────────── 分钟 (0 - 59)
3. 常用时间设置示例
示例 | 说明 |
---|---|
* * * * * | 每分钟执行一次 |
*/5 * * * * | 每5分钟执行一次 |
0 * * * * | 每小时执行一次(整点) |
0 0 * * * | 每天午夜执行 |
0 9 * * 1-5 | 工作日早上9点执行 |
30 8 1 * * | 每月1日上午8:30执行 |
0 20 * * 6 | 每周六晚上8点执行 |
0 0 1 1 * | 每年1月1日午夜执行 |
@reboot | 系统启动时执行 |
@daily 或 0 0 * * * | 每天执行一次 |
@hourly 或 0 * * * * | 每小时执行一次 |
4. 实际添加任务示例
示例1:每天凌晨3点执行备份脚本
0 3 * * * /home/user/scripts/backup.sh
示例2:每30分钟执行一次Python脚本
*/30 * * * * /usr/bin/python3 /home/user/scripts/monitor.py
示例3:每周一至周五上午9:15发送邮件
15 9 * * 1-5 /usr/bin/php /var/www/send_report.php
5. 环境变量和路径问题
由于 cron 的环境与用户环境不同,建议:
- 使用绝对路径
- 在脚本中设置必要的环境变量
- 或者直接在crontab中定义环境变量
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 * * * * /path/to/command
6. 输出重定向
默认情况下,cron 会通过邮件发送任务输出,可以重定向输出:
# 将输出重定向到文件
0 * * * * /path/to/command > /var/log/command.log 2>&1
# 丢弃所有输出
0 * * * * /path/to/command > /dev/null 2>&1
7. 特殊字符转义
如果命令中包含特殊字符(如%),需要进行转义:
0 1 * * * touch /tmp/example_$(date +\%Y\%m\%d).log
8. 检查 cron 日志
查看 cron 执行记录(日志位置可能因系统而异):
# Ubuntu/Debian
grep CRON /var/log/syslog
# CentOS/RHEL
grep CRON /var/log/cron
9. 系统级 crontab
系统级 crontab 位于 /etc/crontab
和 /etc/cron.d/
目录,格式略有不同,需要指定用户:
# /etc/crontab 格式
* * * * * username command_to_execute
10. 最佳实践
- 每个任务添加注释说明
- 复杂的任务逻辑写在脚本中,cron只调用脚本
- 测试时可以先设置每分钟执行一次,确认无误后再调整时间
- 重要的任务添加错误处理机制
- 记录任务执行日志
11. 实际案例
完整的 crontab 示例文件
# 设置环境变量
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# 每天凌晨3点执行数据库备份
0 3 * * * /home/user/scripts/db_backup.sh > /var/log/db_backup.log 2>&1
# 每30分钟检查一次服务器状态
*/30 * * * * /usr/bin/python3 /home/user/scripts/server_monitor.py
# 每周一早上8点清理临时文件
0 8 * * 1 /bin/rm -rf /tmp/*
# 每月1日午夜生成月度报告
0 0 1 * * /usr/bin/php /var/www/generate_monthly_report.php
通过以上方法,您可以有效地使用 crontab 来管理各种定时任务。