Linux定时任务使用(cron)
一、为什么需要定时任务?
这个其实是我在工作当中遇到的一个问题,我需要在非工作时间,比如晚上0点,自动执行一个脚本,来重启算法服务。这其实也是卡在一个其他客户不用上班的时间,工作时间点肯定就不能进行算法服务的重启操作了,这对于客户的损失是比较大的。因此,借此场景来学习Linux定时任务的设置。
Linux设置定时任务的好处如下:
- 设置自动化重复工作,解放双手
- 保障系统维护在非工作时间执行
- 确保关键任务按时完成,避免人为遗忘
二、核心工具:cron与at
Linux系统提供了多种定时任务工具,其中最常用的有cron和at,此外还有batch、systemd-timer等工具。不过目前主要使用的是cron和at。因此,下面主要介绍这两个工具的使用。
2.1 cron:最常用的周期性定时任务系统
什么是cron?
cron是Linux系统中最经典、最常用的定时任务调度器,用于周期性执行命令或脚本。它通过crontab文件定义任务,由cron守护进程(crond)在后台持续运行并检查任务执行时间,其中系统级任务存储在/etc/crontab和/etc/cron.d/目录下,用户级任务通过crontab命令管理。
工作原理:
- 用户创建或编辑任务:用户通过
crontab
命令创建或编辑定时任务。执行crontab -e
命令时,系统会调用默认的文本编辑器打开一个临时文件,用户可以在其中按照cron
的语法格式添加、修改或删除定时任务。编辑完成并保存退出后,该文件内容会被处理成合法的定时任务信息。 - 任务存储:经过处理的定时任务信息会被保存到
/var/spool/cron/
目录下以用户名命名的专属文件中。每个用户的定时任务都独立存储在该目录下对应的文件里,保证了不同用户任务的隔离性。 - 守护进程检查:
crond
守护进程在系统后台持续运行,每分钟会对/var/spool/cron/
目录下的所有用户专属文件,以及/etc/crontab
和/etc/cron.d/
目录下的系统级任务文件进行一次全面检查。它会解析每个任务的时间表达式,判断是否有任务到达执行时间。 - 任务执行:当
crond
守护进程检查到某个任务到达指定的执行时间时,会fork
一个子进程来执行该任务。之所以创建子进程,是为了保证crond
守护进程本身可以继续正常运行,不受任务执行的影响。任务执行完成后,子进程会自动结束。
优点:
- 支持复杂的时间表达式,可精确到分钟级别
- 任务执行结果可通过邮件通知(默认配置)
- 支持系统级和用户级任务分离
- 几乎所有Linux发行版都预装并默认启用
缺点:
- 配置相对复杂,需要记忆特殊字符的含义
- 不支持任务依赖关系
- 当系统关机或重启时,错过的任务不会自动执行(需配合anacron解决)
适用场景:
- 需要定期执行的系统维护任务(如日志清理、备份)
- 周期性的数据处理或报表生成
- 定时启动/关闭服务或应用程序
crontab命令:管理定时任务的入口
crontab -e
:编辑当前用户的定时任务crontab -l
:列出当前用户的定时任务crontab -r
:删除当前用户的所有定时任务crontab -u username -e
:编辑指定用户的定时任务(需要root权限)
2.2 at:一次性定时任务工具
什么是at?
at 是用于执行一次性定时任务的工具,可在指定时间点执行一次命令或脚本。与 cron 不同,at 任务执行完毕后会自动删除,由 atd 守护进程负责管理和执行。
工作原理:
- 用户创建任务:用户使用
at
命令指定任务的执行时间和要执行的命令。at
命令支持多种时间指定方式,如绝对时间(例如at 23:00 tomorrow
)和相对时间(例如at now + 30 minutes
)。执行命令后,用户需要输入要执行的具体命令,输入完成后按Ctrl + D
结束输入。 - 任务存储:输入完成后,系统会对任务信息进行处理,将任务保存到
/var/spool/at/
目录下。任务会被存储为一个文件,文件名包含任务的唯一标识,确保每个任务都能被准确识别和管理。 - 守护进程检查:
atd
守护进程在系统后台持续运行,每分钟会检查/var/spool/at/
目录下的任务文件。它会解析每个任务文件中的时间信息,判断是否有任务到达执行时间。 - 任务执行与清理:当
atd
守护进程检查到某个任务到达指定的执行时间时,会fork
一个子进程来执行该任务。这样可以保证atd
守护进程本身能够继续正常运行,不受任务执行的影响。任务执行完成后,atd
会自动删除对应的任务文件,清理任务记录。
这里给个一个简单的 at
命令使用示例,该示例会在明天 10 点执行关机命令(使用at
要确保Linux已经安装了这个命令):
1 | at 10:00 tomorrow # 先执行命令 |
优点:
- 语法简单直观,容易学习和使用
- 适合临时的、一次性的任务调度
- 支持多种时间指定方式(如绝对时间、相对时间)
缺点:
- 不支持周期性任务
- 任务执行结果默认通过邮件发送,可能被忽略
- 当系统关机或重启时,错过的任务不会自动执行
适用场景:
- 延迟执行某个命令(如30分钟后关闭系统)
- 在特定时间点执行一次性数据处理
- 安排在非工作时间执行的临时任务
与cron的主要区别:
- cron用于周期性任务,at用于一次性任务
- cron任务会被保存并重复执行,at任务执行后自动删除
- cron配置相对复杂,at语法更简单直观
2.3 其他定时任务工具
batch 是一个用于在系统负载较低时执行一次性任务的工具。它与 at
类似,但不指定具体执行时间,而是在系统负载低于某个阈值时才执行,适合用于执行资源密集型任务,以此避免影响系统正常运行。
systemd-timer:新时代的定时任务方案:随着systemd的普及,systemd-timer逐渐成为替代cron的新选择。它支持更精确的时间控制、任务依赖关系和事件触发,配置灵活,但学习曲线较陡峭。
三、cron基础使用教程
目前我在工作中所使用的也是cron居多,基本上都是要在服务器上执行一些定时任务,这个cron
使用起来较为简单,很快就可以把一个定时任务给编写出来。下面具体介绍一下cron
的基础使用方式。
3.1 基本语法与格式
cron
的配置文件遵循严格的语法格式,每行代表一个定时任务,格式如下:
1 | 分 时 日 月 周 要执行的命令 |
时间字段详细解析
- 分:取值范围 0-59,表示分钟
- 时:取值范围 0-23,表示小时
- 日:取值范围 1-31,表示日期
- 月:取值范围 1-12,表示月份
- 周:取值范围 0-7(0和7都代表星期日),表示星期几
特殊字符含义及示例
*
:表示所有可能的值,例如在”分”字段使用*
,表示每分钟执行一次/
:表示间隔,例如在”分”字段使用*/5
,表示每5分钟执行一次-
:表示范围,例如在”时”字段使用9-17
,表示9点到17点之间每个小时执行一次,
:表示多个值,例如在”周”字段使用1,3,5
,表示周一、周三、周五执行
通过上面时间字段+特殊字符,我们可以组合出各种不同的定时任务。具体怎么组合就要看实际的业务场景了,同时也需要大家发挥自己的创意和经验🌈。下面给出一些组合的示例。
示例效果说明:
0 8 * * * command
:每天早上8点整执行命令*/15 * * * * command
:每15分钟执行一次命令0 12 * * 1-5 command
:周一至周五中午12点执行命令30 2 1,15 * * command
:每月1日和15日凌晨2点30分执行命令
3.2 常用命令速查
crontab -e
:编辑定时任务
使用步骤:
- 执行命令后,系统会打开默认文本编辑器(通常是vi或nano)
- 在编辑器中按照cron语法添加或修改任务
- 保存并退出编辑器,任务会自动生效
效果:添加或更新用户的定时任务列表
crontab -l
:查看当前任务
使用步骤:直接在终端执行命令
效果:以文本形式显示当前用户的所有定时任务
crontab -r
:删除所有任务
使用步骤:直接在终端执行命令(注意:此操作不可逆)
效果:删除当前用户的所有定时任务
警告:使用此命令前请务必先用crontab -l
备份任务列表
crontab -u username -e
:管理其他用户的任务
使用步骤:
- 以root用户身份执行命令
- 编辑指定用户的定时任务
- 保存并退出编辑器
效果:添加或更新指定用户的定时任务列表
权限要求:需要root权限才能管理其他用户的任务
四、实用示例:服务场景配置
下面以”每日凌晨2点自动备份数据库”为例,详细演示从crontab -e
开始到任务设置完成的完整流程。
4.1 场景需求
每天凌晨2点自动备份MySQL数据库,并将备份文件压缩存储到指定目录。
4.2 实现步骤
步骤1:创建备份脚本
首先,我们需要创建一个数据库备份脚本:
1 | # 创建备份脚本文件 |
在脚本中添加以下内容:
1 |
|
保存并退出编辑器,然后为脚本添加执行权限:
1 | chmod +x /backup/scripts/mysql_backup.sh |
上面的脚本可以是任何任务,比如我实际业务遇到的算法服务,需要定时调用接口,或者定时调用脚本。下面的步骤是通用的,只需要把要执行的命令替换为实际的命令即可。
步骤2:使用crontab -e
添加定时任务
执行以下命令编辑定时任务:
1 | crontab -e |
系统会打开默认文本编辑器(通常会是vim,当然我的Linux默认是vim啦)。在编辑器中添加以下行:
1 | 0 2 * * * /backup/scripts/mysql_backup.sh |
这表示每天凌晨2点(0分2时)执行备份脚本。
这里面的命令是要执行的命令,比如我上面的脚本,就是要执行的命令。也就是说你Linux怎么启动或者重启脚本,这里就怎么写!!本质上就是让Linux帮你在两点钟执行后面那个命令🤖
步骤3:保存并退出编辑器
- 如果使用vi编辑器:按
Esc
键,然后输入:wq
并按Enter
键保存退出 - 如果使用nano编辑器:按
Ctrl+O
保存,按Ctrl+X
退出 - 如果使用vim编辑器:按
:wq
并按Enter
键保存退出
步骤4:验证定时任务是否添加成功
执行以下命令查看当前用户的定时任务:
1 | crontab -l |
如果成功添加,会看到类似以下输出:
1 | 0 2 * * * /backup/scripts/mysql_backup.sh |
给大家看一下Linux实际的输出会是什么样子的?这是我自己设置的重启systemctl
服务,重启脚本的时间是0点。
五、避坑指南:常见问题排查
- 定时任务不执行?检查这几点
- 命令路径是否正确
- 环境变量是否配置
- 文件权限是否足够
这里要补充一下,命令路径最好写绝对路径,不要写相对路径。因为定时任务是在系统后台执行的,所以相对路径是相对于系统的根目录,而不是相对于当前用户的目录。其次,要注意文件权限的设置,不同的用户有不同的权限,所以要根据实际情况来设置⌨