crontab
是Unix/Linux系统中用于设置周期性任务的工具,通过编辑配置文件实现定时执行命令或脚本。以下是其语法规则和核心要点:
一、基本格式
* * * * * command
- - - - -
| | | | |
| | | | +----- 星期几(0-7,0和7代表周日)
| | | +---------- 月份(1-12或Jan-Dec)
| | +--------------- 日期(1-31)
| +-------------------- 小时(0-23)
+------------------------- 分钟(0-59)
示例:
0 2 * * * /usr/bin/backup.sh # 每天凌晨2点执行备份脚本
二、时间字段详解
1. 分钟(0-59)
*
:每分钟执行一次。*/5
:每5分钟执行一次(等同于0,5,10,...,55
)。15,30
:每小时的15分和30分执行。1-10
:每小时的1到10分钟执行。
2. 小时(0-23)
*
:每小时执行一次。8-17
:每天8点到17点(工作时间)执行。22
:每天22点(晚上10点)执行。
3. 日期(1-31)
*
:每月任意日期执行。1
:每月1号执行。1,15
:每月1号和15号执行。1-7
:每月1号到7号执行。
4. 月份(1-12或Jan-Dec)
*
:每年任意月份执行。12
:每年12月执行。3-6
:每年3月到6月执行。
5. 星期几(0-7,0和7代表周日)
*
:每周任意一天执行。0
:每周日执行。1-5
:每周一到周五执行。6
:每周六执行。SUN
:等价于0
(支持英文缩写)。
三、特殊符号与快捷方式
1. 通配符与操作符
*
:匹配所有值(例如* * * * *
表示每分钟执行)。,
:分隔多个值(例如1,3,5
表示1号、3号、5号)。-
:指定范围(例如8-10
表示8点到10点)。/
:步长间隔(例如*/15
表示每15分钟一次)。
2. 预定义快捷方式
@reboot
:系统重启后执行一次。@yearly
:每年1月1日0点执行(等价于0 0 1 1 *
)。@monthly
:每月1日0点执行(等价于0 0 1 * *
)。@weekly
:每周日0点执行(等价于0 0 * * 0
)。@daily
:每天0点执行(等价于0 0 * * *
)。@hourly
:每小时0分执行(等价于0 * * * *
)。
3. 特殊处理
- %符号:在命令中表示换行,需用
\%
转义(例如date +\%Y\%m\%d
)。 - 日期与星期组合:若同时设置日期和星期(如
0 0 15 * 1
),任务会在满足任一条件时执行,可能导致意外触发,需谨慎使用。
四、命令与执行细节
-
命令路径:
- 必须使用绝对路径(例如
/usr/bin/backup.sh
),避免因环境变量缺失导致执行失败。 - 若依赖特定环境变量,可在命令前加载(例如
. /etc/profile; /path/to/script.sh
)。
- 必须使用绝对路径(例如
-
输出重定向:
- 默认将输出通过邮件发送给用户,可通过以下方式屏蔽:
0 2 * * * /usr/bin/backup.sh >> /dev/null 2>&1 # 标准输出和错误输出重定向到黑洞
- 若需记录日志,可指定文件:
0 2 * * * /usr/bin/backup.sh >> /var/log/backup.log 2>&1
- 默认将输出通过邮件发送给用户,可通过以下方式屏蔽:
-
用户权限:
- 普通用户通过
crontab -e
编辑个人任务,系统级任务需修改/etc/crontab
或/etc/cron.d/
下的文件。 - 通过
cron.allow
和cron.deny
文件控制用户是否有权限使用crontab
。
- 普通用户通过
五、示例与场景
-
每分钟执行:
* * * * * /usr/bin/monitor.sh # 实时监控系统状态
-
每周一至周五下午5点执行:
0 17 * * 1-5 /usr/bin/send-report.sh # 发送工作日报告
-
每月最后一天执行:
0 0 L * * /usr/bin/monthly-cleanup.sh # L代表每月最后一天(部分系统支持)
-
系统重启后执行:
@reboot /usr/bin/start-services.sh # 启动服务
-
每两小时执行:
0 */2 * * * /usr/bin/check-status.sh # 每小时0分执行,间隔2小时
六、注意事项
-
时区问题:
crontab
使用系统时区,若需跨时区执行任务,需在脚本中显式指定时区(例如TZ=Asia/Shanghai
)。
-
并发控制:
- 若任务执行时间较长,需避免重复触发。可通过锁文件(如
flock
)或cron
的withChain
机制(如Go的cron.SkipIfStillRunning
)实现。
- 若任务执行时间较长,需避免重复触发。可通过锁文件(如
-
调试与日志:
- 查看系统日志:
tail -f /var/log/cron
(部分系统路径为/var/log/syslog
)。 - 测试任务时,可临时缩短时间间隔(如
*/1 * * * *
)并观察输出。
- 查看系统日志:
-
系统差异:
- 不同Unix变体(如HP-UX、AIX)对
*/n
语法的支持可能不同,需用列举法替代(如0,20,40 * * * *
表示每20分钟一次)。
- 不同Unix变体(如HP-UX、AIX)对
七、管理命令
命令 | 说明 |
---|---|
crontab -e | 编辑当前用户的定时任务 |
crontab -l | 列出当前用户的定时任务 |
crontab -r | 删除当前用户的所有定时任务 |
crontab -u user -e | 编辑指定用户的定时任务(需root权限) |
系统级任务配置文件:
/etc/crontab
:全局任务配置,可指定执行用户(如root
)。/etc/cron.d/
:存放系统级定时任务文件,支持更灵活的配置。
八、特别示例
0 0/10 * * *
┬ ┬ ┬ ┬ ┬
│ │ │ │ │
│ │ │ │ └─ 星期几 (0-7, 0和7都代表周日)
│ │ │ └─── 月份 (1-12)
│ │ └───── 日期 (1-31)
│ └─────── 小时 (0-23)
└───────── 分钟 (0-59)
详细解释:
- 分钟字段:
0
表示每小时的第0分钟(即整点) - 小时字段:
0/10
表示从0点开始,每隔10小时执行一次(即0点、10点、20点) - 日期字段:
*
表示每天 - 月份字段:
*
表示每月 - 星期字段:
*
表示每周的每一天
执行时间:
这个表达式会在每天的 00:00、10:00 和 20:00 准时执行任务。
常见误区提醒:
如果你的意图是每10分钟执行一次,正确的表达式应该是:
*/10 * * * * # 注意分钟字段的写法
0 0/10 * * *
是每10小时执行一次,且仅在整点触发。请根据实际需求确认是否符合预期。
九、常见错误与排查
-
任务未执行:
- 检查命令路径是否正确。
- 确认时间表达式是否符合预期(可用在线工具验证,如Cron Expression Generator)。
- 查看日志确认是否有权限或路径错误。
-
输出未重定向:
- 检查是否遗漏
2>&1
,导致错误输出未被捕获。
- 检查是否遗漏
-
环境变量缺失:
- 在命令前显式加载环境变量(如
. /etc/profile
),或使用which
获取命令绝对路径。
- 在命令前显式加载环境变量(如
通过合理使用crontab
,可高效实现自动化运维、数据备份、监控等任务。掌握其语法规则和执行细节,能显著提升系统管理效率。