Linux 定时任务全指南:at 与 crontab 详解
在 Linux 系统中,定时任务是自动化运维的核心工具,能够帮助用户在指定时间自动执行脚本或命令。本文将详细介绍两种常用的定时任务工具:at(一次性任务)和 crontab(周期性任务),包括它们的使用方法、配置规则及实战技巧。
at:一次性定时任务
at 工具用于安排在未来某个特定时间执行一次的任务(如临时备份、定时发送邮件),依赖 atd 服务。
启动 atd 服务
at 命令需要 atd 守护进程支持,使用前需确保服务已启动:
1 | # 启动 atd 服务 |
at 命令基本用法
1 | at [选项] 时间 |
常用选项
-f 脚本文件:指定要执行的脚本(默认从标准输入读取命令)。-m:任务执行完成后,通过邮件通知用户(需系统配置邮件服务)。-c 作业号:查看指定作业的具体内容。
时间格式
at 支持多种时间表达方式,灵活易用:
- 绝对时间:
HH:MM(如14:30表示下午 2:30)。HH:MM YYYY-MM-DD(如08:00 2024-10-01表示 2024 年 10 月 1 日 8:00)。HH:MM [am|pm] [月] [日](如3pm 12 25表示 12 月 25 日下午 3 点)。
- 相对时间:
now + 数字 [minutes|hours|days|weeks](如now + 30 minutes表示 30 分钟后,now + 2 days表示 2 天后)。
示例
1 | # 10 分钟后执行 "echo '任务执行'" 命令 |
管理 at 任务
列出等待执行的任务:
1
2
3atq
# 输出格式:作业号 执行时间 队列 用户
# 示例:1 Fri Oct 1 09:00:00 2024 a root删除指定任务:
1
2
3atrm 作业号
# 示例:删除作业号为 1 的任务
atrm 1
crontab:周期性定时任务
crontab 用于创建周期性重复执行的任务(如每日备份、每小时日志清理),依赖 crond 服务,是生产环境中最常用的定时任务工具。
启动 crond 服务
1 | # 启动 crond 服务 |
crontab 命令基本用法
1 | crontab [选项] |
常用选项
-e:编辑当前用户的定时任务(首次使用会提示选择编辑器)。-l:列出当前用户的所有定时任务。-r:删除当前用户的所有定时任务(谨慎使用)。-u 用户名:管理指定用户的定时任务(需 root 权限)。
切换编辑器
默认编辑器可能为 nano,可通过以下命令切换为 vim:
1 | select-editor |
时间表达式规则
crontab 的核心是时间表达式,格式为5 个字段,分别代表:
1 | * * * * * 命令或脚本路径 |
特殊符号
通过特殊符号可灵活定义执行周期:
*:匹配任意值(如分钟位为*表示每分钟)。,:指定多个不连续的值(如0 8,18 * * *表示每天 8 点和 18 点)。-:指定连续范围(如0 9-17 * * 1-5表示工作日 9 点到 17 点每小时执行)。*/n:每隔 n 单位执行(如*/10 * * * *表示每 10 分钟执行)。
示例
| 时间表达式 | 含义 |
|---|---|
0 3 * * * |
每天凌晨 3 点执行 |
0 12 * * 1 |
每周一中午 12 点执行 |
30 8 1 * * |
每月 1 日早上 8:30 执行 |
*/15 * * * * |
每 15 分钟执行一次 |
0 0 * * 5 |
每周五午夜 12 点执行(每周备份) |
0 2 1,15 * * |
每月 1 日和 15 日凌晨 2 点执行 |
配置文件与系统级任务
(1)用户级任务
用户通过 crontab -e 编辑的任务保存在 /var/spool/cron/crontabs/用户名 文件中,仅对该用户生效。
(2)系统级任务
系统级任务适用于所有用户,需编辑 /etc/crontab 配置文件(需 root 权限),格式与用户级任务略有不同,多了用户字段:
1 | # 分钟 小时 日 月 周 用户 命令 |
(3)预配置的周期目录
系统默认提供 4 个周期性任务目录,脚本放入对应目录后会自动按周期执行:
/etc/cron.hourly/:每小时执行一次。/etc/cron.daily/:每天执行一次。/etc/cron.weekly/:每周执行一次。/etc/cron.monthly/:每月执行一次。
注意:放入这些目录的脚本需有可执行权限(chmod +x 脚本名),且不能带扩展名(如 backup 而非 backup.sh)。
管理与调试 crontab 任务
(1)查看任务
1 | # 查看当前用户任务 |
(2)日志查看
crontab 执行日志默认保存在以下位置,可用于调试任务是否执行:
- CentOS:
/var/log/cron - Ubuntu:
/var/log/syslog(需过滤cron关键字)
1 | # 查看最近的 cron 日志 |
(3)常见问题排查
- 任务未执行:
- 检查脚本路径是否正确(建议使用绝对路径,如
/home/user/script.sh而非./script.sh)。 - 脚本是否有可执行权限(
chmod +x 脚本)。 - 环境变量问题:crontab 执行环境变量较少,建议在脚本中显式指定环境变量(如
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin)。
- 检查脚本路径是否正确(建议使用绝对路径,如
- 邮件通知:若任务执行失败,系统可能发送邮件到
/var/spool/mail/用户名,可查看邮件内容定位错误。
at 与 crontab 的对比与选择
| 工具 | 适用场景 | 优势 | 局限性 |
|---|---|---|---|
at |
一次性任务(如临时备份) | 简单直观,时间表达灵活 | 仅执行一次,不适合周期性任务 |
crontab |
周期性任务(如日志清理) | 支持复杂周期,系统级 / 用户级任务分离 | 配置相对复杂,需学习时间表达式 |
选择建议:
- 临时的、一次性的任务 → 使用
at。 - 长期的、周期性的任务 → 使用
crontab。
实战案例
案例 1:每日凌晨 2 点备份 MySQL 数据库(crontab)
创建备份脚本
backup_mysql.sh:1
2
3
4
5
6
7
8
9
10
BACKUP_DIR="/data/backup/mysql"
DATE=$(date +%Y%m%d)
mkdir -p $BACKUP_DIR
# 备份命令(需替换用户名和密码)
mysqldump -u root -p123456 --all-databases > $BACKUP_DIR/mysql_$DATE.sql
# 压缩备份文件
gzip $BACKUP_DIR/mysql_$DATE.sql
# 删除 7 天前的备份
find $BACKUP_DIR -name "mysql_*.sql.gz" -mtime +7 -delete赋予执行权限:
1
chmod +x backup_mysql.sh
添加到 crontab:
1
2
3crontab -e
# 添加以下内容(每天凌晨 2 点执行)
0 2 * * * /home/user/backup_mysql.sh
案例 2:30 分钟后清理临时文件(at)
1 | # 30 分钟后执行清理命令 |