第 46 课:cron 定时任务
所属模块: Shell 脚本进阶 难度: 中级 标签: cron, scheduling, 定时任务, Linux运维
1. 学习目标
通过本节课的学习,你将能够:
- 理解 cron 的工作原理及其在系统运维中的作用。
- 掌握 crontab 文件的语法,能够编写正确的定时任务指令。
- 熟练使用
crontab命令来查看、编辑和管理用户的定时任务。 - 了解系统级定时任务与用户级定时任务的区别。
- 能够检查 cron 任务的运行状态,并排查常见的任务执行失败问题。
2. 核心概念
想象一下,你需要在每天凌晨2点自动备份数据库,或者在每周五下午清理日志文件。手动执行这些重复性任务既繁琐又容易遗忘。这时,cron 就是你的得力助手。
cron 是一个 Linux/Unix 系统下的定时任务守护进程。它会周期性地检查一个称为 “crontab”(cron table)的配置文件,看看到了设定的时间,有没有需要执行的任务。可以把它理解为一个 24小时待命的自动化调度员。
crontab 文件格式
一个 crontab 条目由 6 或 7 个字段 组成,前5个字段用于定义时间,最后一个字段是需要执行的命令。
* * * * * command_to_execute
| | | | |
| | | | +----- 星期几 (0 - 7) (星期天为0或7)
| | | +------- 月份 (1 - 12)
| | +--------- 日期 (1 - 31)
| +----------- 小时 (0 - 23)
+------------- 分钟 (0 - 59)
特殊字符说明:
*:表示任意时间。例如,* * * * *表示每分钟执行一次。,:表示列举多个值。例如,1,15,30 * * * *表示在每小时的第1、15、30分钟执行。-:表示一个范围。例如,* 9-17 * * *表示从9点到17点之间的每小时。/:表示步长。例如,*/5 * * * *表示每5分钟执行一次。
特殊字符串: cron 还支持一些常用的别名,让配置更清晰:
@reboot:系统启动时运行一次。@yearly或@annually:每年运行一次(0 0 1 1 *)。@monthly:每月运行一次(0 0 1 * *)。@weekly:每周运行一次(0 0 * * 0)。@daily或@midnight:每天运行一次(0 0 * * *)。@hourly:每小时运行一次(0 * * * *)。
用户级 vs 系统级任务
- 用户级任务:通过
crontab -e命令编辑,存储在/var/spool/cron/crontabs/目录下(文件名通常是用户名)。每个用户可以管理自己的任务。 - 系统级任务:直接编辑
/etc/crontab文件或放在/etc/cron.d/、/etc/cron.daily/、/etc/cron.hourly/等目录下的脚本。这些任务通常需要root权限,用于执行系统维护。
3. 代码示例
示例1:基本的 crontab 操作
# 1. 查看当前用户的定时任务列表
crontab -l
# 2. 编辑当前用户的定时任务(会使用默认编辑器打开,如vi或nano)
crontab -e
# 3. 删除当前用户的所有定时任务(谨慎使用!)
# crontab -r
示例2:添加一个定时任务
假设我们有一个备份脚本 /home/user/backup.sh,希望它每天凌晨3点15分执行。
# 首先,确保脚本有执行权限
chmod +x /home/user/backup.sh
# 然后,编辑crontab
crontab -e
在打开的编辑器中,添加以下一行:
# 每天凌晨3:15执行备份脚本
15 3 * * * /home/user/backup.sh
保存并退出。cron 会自动加载新的配置。
示例3:系统级定时任务示例
编辑 /etc/crontab 文件(需要root权限):
sudo vi /etc/crontab
在文件末尾可以添加如下内容(注意,系统级crontab比用户级多了一个“用户”字段):
# 每周一至周五的上午9点,以root身份运行系统检查
0 9 * * 1-5 root /usr/local/bin/system_check.sh
4. 实践练习
练习1:添加一个每5分钟记录一次系统时间的任务
要求:
- 编写一个简单的Shell命令,将当前时间追加写入文件
/tmp/cron_test.log。 - 使用
crontab -e设置为每5分钟执行一次。 - 等待几分钟后,使用
tail -f /tmp/cron_test.log查看任务是否正常执行。
预期输出示例:
Mon Nov 27 10:05:01 CST 2023
Mon Nov 27 10:10:01 CST 2023
Mon Nov 27 10:15:01 CST 2023
练习2:使用特殊字符串配置任务
要求:
配置一个任务,在系统每次启动后,向你的家目录下的 startup_log.txt 文件写入一行启动记录。
提示:使用 @reboot。
练习3:组合脚本与定时任务
要求:
- 编写一个Shell脚本
disk_usage_alert.sh,当根分区使用率超过80%时,向/var/log/disk_alert.log文件记录一条警告信息。 - 设置一个cron任务,让这个脚本每天下午6点运行。
- 思考:如果需要将警告信息通过邮件发送给自己,脚本应如何修改?(提示:使用
mail命令)
5. 常见错误
-
环境变量问题:cron 执行任务时的环境变量与你在终端登录时不同。它通常只有最基本的
PATH(如/usr/bin:/bin)。因此,在命令中最好使用绝对路径。- 错误写法:
python my_script.py - 正确写法:
/usr/bin/python3 /home/user/scripts/my_script.py
- 错误写法:
-
脚本权限问题:要执行的脚本文件必须具有执行权限 (
chmod +x script.sh)。 -
输出重定向问题:如果任务有输出(标准输出或错误输出),cron 会尝试通过邮件发送给用户。如果你不想收到邮件或邮件服务未配置,应该重定向输出。
15 3 * * * /home/user/backup.sh > /var/log/backup.log 2>&1
-
分钟和小时字段混淆:记住顺序是 分 时 日 月 周。想设置“每天上午10点30分”,应该是
30 10 * * *,而不是10 30 * * *。 -
调试困难:当任务未执行时,如何排查?
- 首先检查语法:
crontab -l查看任务是否被正确保存。 - 查看系统日志:cron 的活动日志通常记录在
/var/log/cron或/var/log/syslog中,使用grep CRON /var/log/syslog来过滤查看。 - 手动运行测试:在终端中直接运行任务命令,看是否报错。
- 首先检查语法:
6. 小结
本节课我们学习了 Linux 系统中强大的定时任务调度工具——cron。
- 核心是 crontab 文件:通过5个时间字段和命令来定义任务的执行计划。
- 使用
crontab命令管理:crontab -e编辑,crontab -l查看。 - 注意执行环境:cron 环境干净,务必使用绝对路径并妥善处理输出重定向。
- 善用日志调试:
/var/log/syslog是排查 cron 问题的首选工具。
掌握 cron 是 Linux 系统管理员和开发者的必备技能,它能极大地提升工作的自动化程度和可靠性。下一课我们将学习另一种一次性任务调度工具——at 和 batch。