46·Shell 脚本进阶进阶

cron 定时任务

cronscheduling

第 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分钟记录一次系统时间的任务

要求:

  1. 编写一个简单的Shell命令,将当前时间追加写入文件 /tmp/cron_test.log
  2. 使用 crontab -e 设置为每5分钟执行一次。
  3. 等待几分钟后,使用 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:组合脚本与定时任务

要求:

  1. 编写一个Shell脚本 disk_usage_alert.sh,当根分区使用率超过80%时,向 /var/log/disk_alert.log 文件记录一条警告信息。
  2. 设置一个cron任务,让这个脚本每天下午6点运行。
  3. 思考:如果需要将警告信息通过邮件发送给自己,脚本应如何修改?(提示:使用 mail 命令)

5. 常见错误

  1. 环境变量问题:cron 执行任务时的环境变量与你在终端登录时不同。它通常只有最基本的 PATH(如 /usr/bin:/bin)。因此,在命令中最好使用绝对路径

    • 错误写法python my_script.py
    • 正确写法/usr/bin/python3 /home/user/scripts/my_script.py
  2. 脚本权限问题:要执行的脚本文件必须具有执行权限 (chmod +x script.sh)。

  3. 输出重定向问题:如果任务有输出(标准输出或错误输出),cron 会尝试通过邮件发送给用户。如果你不想收到邮件或邮件服务未配置,应该重定向输出。

    • 15 3 * * * /home/user/backup.sh > /var/log/backup.log 2>&1
  4. 分钟和小时字段混淆:记住顺序是 分 时 日 月 周。想设置“每天上午10点30分”,应该是 30 10 * * *,而不是 10 30 * * *

  5. 调试困难:当任务未执行时,如何排查?

    • 首先检查语法: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 系统管理员和开发者的必备技能,它能极大地提升工作的自动化程度和可靠性。下一课我们将学习另一种一次性任务调度工具——atbatch

练习编辑器

rust
Loading...

继续学习

完成本课后,建议继续学习下一课「at 与 batch 一次性任务」 以巩固所学知识。