1. 简介
Crontab 是 Linux 和 Unix 系统中用来定时执行任务的工具。它可以让用户在指定时间执行指定的命令或脚本,比如备份文件、清理日志、定期发送邮件等。
Crontab 的主要作用与功能如下:
- 管理定时任务:支持新增、修改、删除等操作。
- 定时执行命令:可以按分钟、小时、日、月、星期等时间维度调度命令或脚本。
- 自动化运维:帮助运维人员定时备份数据、清理垃圾文件、监控系统状态等。
- 提高工作效率:让重复性工作自动完成,减少手工干预。
2. 命令格式
crontab 的命令格式如下:
crontab [-u 用户名] [-l|-e|-r] [-i] [文件名]
参数含义说明:
| 参数 |
说明 |
-u |
指定要操作的用户的用户名,如果不指定,则默认为当前用户。 |
-l |
列出当前用户的所有定时任务。 |
-e |
编辑当前用户的定时任务。 |
-r |
删除当前用户的所有定时任务。 |
-i |
在删除定时任务时进行确认提示。 |
| 文件名 |
指定要安装的定时任务文件,可以是一个普通文本文件,也可以是一个压缩文件。 |
3. Cron 格式说明
crontab使用五个时间字段来定义任务的执行时间:
* * * * * command
# 分钟 小时 日 月 星期 命令
时间字段取值规则:
*:任意值
,:列表值,例如 1,15
-:范围值,例如 1-5
/:步长值,例如 */10
时间字段取值范围:
| 字段 |
允许范围 |
| 分钟 |
0-59 |
| 小时 |
0-23 |
| 日期 |
1-31 |
| 月份 |
1-12 或 JAN-DEC |
| 星期 |
0-7(0 和 7 都表示周日)或 SUN-SAT |
command 则是任何需要执行的命令。
4. 定时任务实例
4.1 为特定时间安排任务
Cron 的基本用法是在特定时间执行一项任务。下面的配置将在 6 月 10 日上午 08:30 执行完整备份 Shell 脚本 full-backup。
这里要注意,时间字段使用的是 24 小时制,因此上午 8 点写 8,晚上 8 点写 20。
30 08 10 06 * /home/haostack/full-backup
- 30:第 30 分钟
- 08:上午 8 点
- 10:第 10 天
- 06:第 6 个月,也就是六月
*:一周中的每一天
4.2 为多个时间点安排任务(例如每天两次)
下面的脚本每天执行两次增量备份。
这条配置会在每天 11:00 和 16:00 执行增量备份脚本 incremental-backup。字段中用逗号分隔的值,表示命令需要在所有列出的时间点都执行一次。
00 11,16 * * * /home/haostack/bin/incremental-backup
- 00:第 0 分钟,也就是整点
- 11,16:上午 11 点和下午 4 点
*:每天
*:每月
*:一周中的每一天
4.3 为特定时间范围安排任务(例如仅工作日)
如果希望任务在特定时间范围内每小时执行一次,可以使用下面的配置。
(1)每天工作时间内执行 Cron 任务
这个示例会在每天上午 9 点至下午 6 点之间,每小时检查一次数据库状态,周末也会执行。
00 09-18 * * * /home/haostack/bin/check-db-status
- 00:第 0 分钟,也就是整点
- 09-18:上午 9 点到下午 6 点之间的每个整点
*:每天
*:每月
*:一周中的每一天
(2)每个工作日工作时间内执行 Cron 任务
这个示例则只在工作日,也就是周一到周五的上午 9 点至下午 6 点之间检查数据库状态。
00 09-18 * * 1-5 /home/haostack/bin/check-db-status
- 00:第 0 分钟,也就是整点
- 09-18:上午 9 点到下午 6 点之间的每个整点
*:每天
*:每月
- 1-5:周一、周二、周三、周四和周五,也就是工作日
4.4 如何查看 Crontab 条目?
(1)查看当前登录用户的 Crontab 条目
要查看当前账户的 crontab 条目,直接执行 crontab -l 即可:
haostack@test-db$ crontab -l
@yearly /home/haostack/annual-maintenance
*/10 * * * * /home/haostack/check-disk-space
注意:这会显示当前登录用户的 crontab。
(2)查看 Root 用户的 Crontab 条目
先以 root 用户登录:
su - root
然后执行:
root@test-db# crontab -l
no crontab for root
(3)查看其他 Linux 用户的 Crontab 条目
要查看其他用户的 crontab 条目,需要以 root 用户登录,并使用 -u {用户名} -l 参数:
root@test-db# crontab -u ymadmin -l
@monthly /home/ymadmin/monthly-backup
00 09-18 * * * /home/ymadmin/check-db-status
4.5 如何编辑 Crontab 条目?
(1)编辑当前登录用户的 Crontab 条目
要编辑 crontab 条目,使用 crontab -e。默认情况下,它会编辑当前登录用户的 crontab。
haostack@test-db$ crontab -e
@yearly /home/haostack/centos/bin/annual-maintenance
*/10 * * * * /home/haostack/debian/bin/check-disk-space
~
"/tmp/crontab.XXXXyjWkHw" 2L, 83C
注意:该命令会在 Vim 编辑器中打开 crontab 文件,cron 会创建一个临时文件 /tmp/crontab.XX...。
保存退出时使用 :wq。保存后,系统会提示 crontab 已成功修改:
~
"crontab.XXXXyjWkHw" 2L, 83C written
crontab: installing new crontab
(2)编辑 Root 用户的 Crontab 条目
先以 root 用户登录:
su - root
然后执行:
root@test-db# crontab -e
(3)编辑其他 Linux 用户的 Crontab 文件条目
以 root 用户登录后,使用 -u {用户名} -e 参数编辑指定用户的 crontab:
root@test-db# crontab -u ymadmin -e
@monthly /home/ymadmin/fedora/bin/monthly-backup
00 09-18 * * * /home/ymadmin/ubuntu/bin/check-db-status
~
~
~
"/tmp/crontab.XXXXyjWkHw" 2L, 83C
4.6 使用 Cron 安排每分钟执行的任务
通常情况下,你可能并不需要每分钟都执行某个任务。不过理解这个示例,对后面其他示例会有帮助。
* * * * * CMD
* 表示所有可能的时间单位,也就是一年中每个小时的每一分钟。除了直接使用 *,它在下面这些场景中也很常用:
- 分钟字段写
*/5,表示每 5 分钟执行一次。
- 分钟字段写
0-10/2,表示前 10 分钟内每 2 分钟执行一次。
同样的写法也适用于其他四个字段。
4.7 安排每 10 分钟执行一次的后台 Cron 任务
如果想每 10 分钟检查一次磁盘空间,可以使用下面的配置:
*/10 * * * * /home/haostack/check-disk-space
它会在一年当中每 10 分钟执行一次 check-disk-space 命令。实际使用时,我们可能只希望在办公时间执行,或者反过来,只希望在非办公时间执行。前面 4.3 节的示例已经展示了如何控制时间范围。
除了在五个时间字段中写具体值之外,cron 还支持用单个关键字来表示时间。在某些特殊情况下,可以用 @ 后跟关键字的方式代替五个时间字段,例如 @reboot、@midnight、@yearly、@hourly 等。
Cron 特殊关键字及其含义如下:
| 关键字 |
等效写法 |
@yearly |
0 0 1 1 * |
@daily |
0 0 * * * |
@hourly |
0 * * * * |
@reboot |
启动时运行 |
4.8 使用 @yearly 安排每年第一分钟执行的任务
如果希望任务在每年的第一分钟执行,可以使用 @yearly 关键字。
下面的配置会在每年 1 月 1 日 00:00 执行 annual-maintenance 脚本,完成系统年度维护:
@yearly /home/haostack/red-hat/bin/annual-maintenance
4.9 使用 @monthly 安排每月初执行的 Cron 任务
这与 @yearly 类似,但 @monthly 会每个月执行一次命令。
下面的配置会在每月 1 日 00:00 执行 tape-backup 脚本:
@monthly /home/haostack/suse/bin/tape-backup
4.10 使用 @daily 安排每天执行的后台任务
使用 @daily 关键字,可以在每天 00:00 执行一次任务。
下面的配置会在每天 00:00 执行 cleanup-logs 脚本,完成每日日志清理:
@daily /home/haostack/arch-linux/bin/cleanup-logs "day started"
4.11 如何使用 @reboot 在每次重启后执行 Linux 命令?
使用 @reboot 关键字,可以在机器每次启动后执行一次指定的命令:
@reboot CMD
4.12 如何使用 MAIL 关键字禁用/重定向 Crontab 邮件输出?
默认情况下,crontab 会把任务输出发送给安排该任务的用户。如果想重定向到指定用户,可以在 crontab 中添加或更新 MAIL 变量。
haostack@test-db$ crontab -l
MAIL="haostack"
@yearly /home/haostack/annual-maintenance
*/10 * * * * /home/haostack/check-disk-space
注意:当前登录用户的 crontab 中包含 MAIL 变量。
如果希望邮件不发送到任何地方,也就是停止通过电子邮件发送 crontab 输出,可以把 MAIL 设置为空:
MAIL=""
4.13 如何使用 Crontab 每秒执行一次 Linux Cron 任务
我们无法安排每秒执行一次的 cron 任务。因为在 cron 中,可以指定的最小时间单位是分钟。而且在实际场景中,大多数情况下也几乎没有理由让某个任务每秒运行一次。
4.14 在 Crontab 中指定 PATH 变量
前面所有示例中,我们都为需要执行的 Linux 命令或 Shell 脚本写明了绝对路径。
例如,如果不想写 /home/haostack/tape-backup,而只写 tape-backup,可以在 crontab 的 PATH 变量中加入路径 /home/haostack:
haostack@test-db$ crontab -l
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/home/haostack
@yearly annual-maintenance
*/10 * * * * check-disk-space
注意:当前登录用户的 crontab 中包含 PATH 变量。
4.15 从 Cron 文件安装 Crontab
除了直接编辑 crontab 文件之外,也可以先把所有条目写入一个 cron 文件。写入完成后,再将该文件上传或安装到 cron 中。
haostack@test-db$ crontab -l
no crontab for haostack
haostack@test-db$ cat cron-file.txt
@yearly /home/haostack/annual-maintenance
*/10 * * * * /home/haostack/check-disk-space
haostack@test-db$ crontab cron-file.txt
haostack@test-db$ crontab -l
@yearly /home/haostack/annual-maintenance
*/10 * * * * /home/haostack/check-disk-space
注意:执行 crontab cron-file.txt 会把该文件安装到当前用户的 crontab 中,同时删除旧的 cron 条目。