定时任务
Linux 定时任务全指南:at 与 crontab 详解
在 Linux 系统中,定时任务是自动化运维的核心工具,能够帮助用户在指定时间自动执行脚本或命令。本文将详细介绍两种常用的定时任务工具:at(一次性任务)和 crontab(周期性任务),包括它们的使用方法、配置规则及实战技巧。
at:一次性定时任务
at 工具用于安排在未来某个特定时间执行一次的任务(如临时备份、定时发送邮件),依赖 atd 服务。
启动 atd 服务
at 命令需要 atd 守护进程支持,使用前需确保服务已启动:
# 启动 atd 服务
sudo service atd start
# 设置开机自启动(CentOS)
sudo chkconfig atd on
# 设置开机自启动(Ubuntu)
sudo systemctl enable atd
at 命令基本用法
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 天后)。
示例
# 10 分钟后执行 "echo '任务执行'" 命令
at now + 10 minutes
> echo '任务执行'
> <按 Ctrl+D 结束输入>
# 指定脚本在明天 9 点执行
at -f backup.sh 09:00 tomorrow
# 查看任务内容(假设作业号为 1)
at -c 1
管理 at 任务
列出等待执行的任务:
atq # 输出格式:作业号 执行时间 队列 用户 # 示例:1 Fri Oct 1 09:00:00 2024 a root删除指定任务:
atrm 作业号 # 示例:删除作业号为 1 的任务 atrm 1
crontab:周期性定时任务
crontab 用于创建周期性重复执行的任务(如每日备份、每小时日志清理),依赖 crond 服务,是生产环境中最常用的定时任务工具。
启动 crond 服务
# 启动 crond 服务
sudo service crond start
# 开机自启动(CentOS)
sudo chkconfig crond on
# 开机自启动(Ubuntu)
sudo systemctl enable cron
crontab 命令基本用法
crontab [选项]
常用选项
-e:编辑当前用户的定时任务(首次使用会提示选择编辑器)。-l:列出当前用户的所有定时任务。-r:删除当前用户的所有定时任务(谨慎使用)。-u 用户名:管理指定用户的定时任务(需 root 权限)。
切换编辑器
默认编辑器可能为 nano,可通过以下命令切换为 vim:
select-editor
# 选择对应编号的 vim 即可
时间表达式规则
crontab 的核心是时间表达式,格式为5 个字段,分别代表:
* * * * * 命令或脚本路径
# 分钟(0-59) 小时(0-23) 日(1-31) 月(1-12) 周(0-7,0和7均为周日)
特殊符号
通过特殊符号可灵活定义执行周期:
*:匹配任意值(如分钟位为*表示每分钟)。,:指定多个不连续的值(如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 权限),格式与用户级任务略有不同,多了用户字段:
# 分钟 小时 日 月 周 用户 命令
0 3 * * * root /usr/local/script/backup.sh
(3)预配置的周期目录
系统默认提供 4 个周期性任务目录,脚本放入对应目录后会自动按周期执行:
/etc/cron.hourly/:每小时执行一次。/etc/cron.daily/:每天执行一次。/etc/cron.weekly/:每周执行一次。/etc/cron.monthly/:每月执行一次。
注意:放入这些目录的脚本需有可执行权限(chmod +x 脚本名),且不能带扩展名(如 backup 而非 backup.sh)。
管理与调试 crontab 任务
(1)查看任务
# 查看当前用户任务
crontab -l
# 查看其他用户任务(需 root 权限)
sudo crontab -l -u 用户名
(2)日志查看
crontab 执行日志默认保存在以下位置,可用于调试任务是否执行:
- CentOS:
/var/log/cron - Ubuntu:
/var/log/syslog(需过滤cron关键字)
# 查看最近的 cron 日志
grep CRON /var/log/syslog
(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: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赋予执行权限:
chmod +x backup_mysql.sh添加到 crontab:
crontab -e # 添加以下内容(每天凌晨 2 点执行) 0 2 * * * /home/user/backup_mysql.sh
案例 2:30 分钟后清理临时文件(at)
# 30 分钟后执行清理命令
at now + 30 minutes
> rm -rf /tmp/*
> <按 Ctrl+D 结束>