一、开篇:为什么需要计划任务?
在 Linux 系统管理中,计划任务是实现自动化的核心机制之一。想象这样的场景:
- 每天凌晨自动清理系统日志
- 每周五下班前执行数据库全量备份
- 每月 1 号生成业务报表并发送邮件
这些重复性工作若通过人工操作,不仅耗时易错,还无法应对大规模集群管理需求。Linux 提供的at
和crontab
工具,正是为解决这类问题而生,让系统按预设时间自动执行任务,解放运维人员的双手。
知识图谱
二、环境准备:构建本地实验环境
2.1 为什么配置本地源?
- 离线安装优势:在无网络环境或测试场景中,通过光驱挂载系统镜像创建本地源,可快速安装
at
、cron
等服务组件。 - 稳定性保障:避免因远程源故障导致的安装失败。
2.2 操作详解(以 Redhat为例)
# 进入yum源配置目录
cd /etc/yum.repos.d/
# 创建base.repo文件并写入以下内容
cat > base.repo << EOF
[base]
name=base
baseurl=file:///mnt/BaseOS
gpgcheck=0
[app]
name=appstream
baseurl=file:///mnt/AppStream
gpgcheck=0
EOF
# 挂载光驱到/mnt目录(根据实际设备名调整,如/dev/sr0)
mount /dev/sr0 /mnt
# 验证挂载结果
ls /mnt/AppStream/ # 应显示Packages和repodata目录
ls /mnt/BaseOS/ # 同上
2.3 环境初始化建议
- 创建新虚拟机并安装系统(建议使用 CentOS 8/9 或 RHEL 8+)
- 安装完成后立即创建快照,便于实验回滚
- 确保系统已安装
cronie
和crontabs
包(通常默认安装,可通过rpm -qa | grep cron
检查)
2.4软件的安装
# 查看软件是否已经安装
[root@redhat-9 ~]# yum whatprovides at 或者 yum whatprovides atd
# 如果没有安装,执行下面的命令安装该软件
[root@redhat-9 ~]# yum install at -y
三、程序启动方式:手动与调度的本质区别
3.1 手动启动
(1)前台启动(如ls
、sleep 10
):直观但阻塞终端,适合交互式操作。
直接执行命令,进程占据当前终端,直至结束:
ls # 前台列出文件(立即结束)
sleep 10 # 前台暂停10秒(期间终端被阻塞)
(2)后台启动(加&):释放终端资源,但需用jobs、fg等命令管理
在命令末尾加&
,进程在后台运行:
sleep 10 & # 后台暂停10秒
[1] 5529 # 输出:任务序号[1]和进程号5529
jobs # 查看后台任务列表
fg %1 # 将任务1调至前台
kill %1 # 终止任务1(%1为任务编号)
3.2 系统调度启动
通过atd
和crond
守护进程实现:
atd
:监听一次性任务队列,适用于临时、非重复的操作(如定时发送通知)。crond
:循环检查周期性任务,适合高频次、规律性的工作(如日志切割、数据同步)。
四、一次性任务神器:at 命令深度解析
4.1 什么是 at?
at
是 Linux 下的单次计划任务工具,通过atd
守护进程在指定时间执行唯一一次任务,常用于临时维护或提醒类操作。
4.2 为什么选择 at?
- 场景举例:
- 明天上午 9 点向团队发送项目进度邮件
- 服务器维护窗口到期后自动重启服务
- 优势:简单直接,无需编写复杂脚本,适合单次操作。
注意事项
- 1.如果设定的时间系统未启动、系统就会在下次开机的时候立马执行该计划任务。
- 2.系统时间已经过了(比如现在19:20,我设置了一个19:15的任务)前提是在这个时间系统是开机的,系统就会在第二天这个时刻执行,如果系统在这个时间未开机,系统就会在下次开机的时候立马执行该任务。
4.3 怎么用 at?
由atd
守护进程负责执行,需确保服务运行:
systemctl start atd # 启动服务
systemctl enable atd # 设置开机自启
基础语法
at [时间] # 进入交互模式指定任务
at -f 文件 时间 # 从文件读取任务内容
at -l # 列出当前系统里面计划任务
# 示例
(1)立即执行任务(5 分钟后)
bash
echo "echo 'Hello, World!'" | at now + 5 minutes
# 或直接进入at交互模式
at now + 5 minutes
> echo 'Hello, World!'
> <Ctrl+D> # 结束输入
(2)通过文件指定任务
bash
echo "touch /tmp/at_test.txt" > task.txt
at -f task.txt now + 20 minutes # 指定任务文件执行
时间格式详解
表达式 | 含义 |
---|---|
now + 10 min | 10 分钟后 |
20:30 2024-12-31 | 2024 年跨年夜 20:30 |
teatime + 2 days | 2 天后的下午 4 点(英国下午茶时间) |
(1)绝对时间
- 12 小时制:
10:30am 2024-12-06
或10:30am 06/12/2024
- 24 小时制:
22:45 2024-12-06
- 简写格式:
06122024
(2024 年 12 月 6 日)
(2)模糊时间
at noon # 中午12点
at midnight # 午夜0点
at teatime # 下午4点(默认)
(3)相对时间
at now + 1 min # 1分钟后
at 4pm + 3 days # 3天后的下午4点
at 1am tomorrow # 明天凌晨1点
4.4 任务管理命令
at -l # 等价于atq,列出所有待执行任务
at -c 14 # 查看任务编号14的具体内容
atrm 1 # 删除任务编号1(等价于at -d 1)
4.5 黑白名单机制
- 权限控制文件:
/etc/at.allow
:允许使用 at 的用户列表(每行一个用户名)/etc/at.deny
:禁止使用 at 的用户列表(优先级低于 allow)
- 规则说明:
- 若
at.allow
存在,仅其中的用户可使用 at(at.deny
被忽略) - 若
at.allow
不存在,检查at.deny
,不在其中的用户可使用 at - 若两者均不存在,仅 root 用户可使用 at
- 若
# 示例:允许user1和user2使用at
echo "user1" > /etc/at.allow
echo "user2" >> /etc/at.allow
chmod 644 /etc/at.allow # 确保只有root可写
4.6 日志追踪
tail -f /var/log/cron # 实时查看任务执行日志
watch -n 1 ls -l /root # 每秒监控/root目录变化(验证任务执行)
4.7 实战案例
案例 1:30 分钟后在 /root 目录创建检查文件
at now + 30 minutes
> touch /root/check_at.txt # 输入任务内容
> <Ctrl+D> # 结束输入并提交任务
# 示例
[root@redhat-9 ~]# at now + 30 minutes
warning: commands will be executed using /bin/sh
at> touch /root/chech_at.txt
at> <EOT>
job 2 at Fri May 16 19:50:00 2025
# 查看
[root@redhat-9 ~]# ll /var/spool/at/
total 8
-rwx------. 1 root root 3306 May 16 19:15 a0000101bc6661
-rwx------. 1 root root 3321 May 16 19:20 a0000201bc62c6
drwx------. 2 root root 6 Apr 4 2022 spool
# 也可以在日志中查看,这里我们设置一个一分钟后执行的任务:
[root@redhat-9 ~]# at 19:24
warning: commands will be executed using /bin/sh
at> wall hahahahha
at> <EOT>
job 4 at Fri May 16 19:24:00 2025
# 查看日志
[root@redhat-9 ~]# tail -f /var/log/cron
Broadcast message from root@redhat-9 (somewhere) (Fri May 16 19:24:00 2025):
hahahahha
May 16 19:24:00 redhat-9 atd[3231]: Starting job 4 (a0000401bc62ac) for user 'root' (0)
案例 2:通过文件批量执行任务
# 创建任务文件
echo "echo 'Task executed at $(date)' >> /var/log/at.log" > at_jobs.txt
echo "systemctl restart httpd" >> at_jobs.txt
# 2小时后执行文件中的任务
at -f at_jobs.txt 14:00 today
五、周期性任务核心:crontab 全流程指南
5.1 什么是 crontab?
crontab
是 Linux 周期性计划任务的配置工具,通过crond
守护进程按固定频率执行任务,广泛用于系统监控、数据备份、日志处理等场景。
5.2 为什么需要 crontab?
- 企业级应用场景:
- 每天凌晨 2 点压缩用户日志(节省磁盘空间)
- 每周三凌晨 3 点执行数据库增量备份
- 每月 1 日生成服务器负载报告并邮件告警
- 核心优势:支持复杂时间表达式,可管理大量用户级任务。
5.3 怎么用 crontab?
- 守护进程:
crond
(需确保运行:systemctl enable --now crond
)
两种配置方式
(1)系统级配置(/etc/crontab)
# 格式:分 时 日 月 周 用户 命令
0 1 * * * root /path/to/script.sh # 每天凌晨1点由root执行脚本
(2)用户级配置(crontab -e)
crontab -e # 编辑当前用户任务
crontab -e -u user1 # 编辑user1的任务
- 系统级:
/etc/crontab
(包含环境变量和全局任务) - 用户级:
/var/spool/cron/<用户名>
(通过crontab -e
编辑)
类型 | 文件路径 | 权限 | 适用场景 |
---|---|---|---|
系统级配置 | /etc/crontab | 644(仅 root 可写) | 全局任务(如系统维护) |
用户级配置 | /var/spool/cron/用户 | 600(仅用户可读写) | 个人任务(如开发脚本) |
5.4 时间格式深度解析
字段 | 范围 | 特殊符号说明 |
---|---|---|
分钟 | 0-59 | * (每分钟)、, (分隔)、- (范围)、/ (步长) |
小时 | 0-23 | 同上 |
日期 | 1-31 | L (最后一天)、W (最近工作日) |
月份 | 1-12 | 可写数字或英文缩写(如 Jan) |
星期 | 0-6(0 = 日) | 1-5 (周一至周五)、7 (周日) |
经典示例:
0 8 * * * # 每天8:00执行
*/15 12 * * * # 每天12点每15分钟执行一次
13 0 1 * * # 每月1日00:13执行
11,23 * * * # 每天11点和23点的每分钟执行
0 2-6/2 * * 1,3,7 # 每周一、三、日,凌晨2、4、6点执行
5.5 任务管理命令
crontab -l # 列出当前用户任务
crontab -l -u user1 # 列出user1的任务
crontab -r # 删除当前用户所有任务(谨慎操作!)
crontab -r -u user1 # 删除user1的任务
时间表达式拆解(分 时 日 月 周)
# 每天8:00执行清理脚本
0 8 * * * /usr/sbin/clean_logs.sh
# 每周一至周五的9:00-18:00每小时执行监控(排除周末)
0 9-18 * * 1-5 /usr/local/monitor/run.sh
# 每月最后一天的凌晨1点执行磁盘检查(L代表最后一天)
0 1 L * * fsck /dev/sda1
实战案例:构建自动化备份系统
需求:每天凌晨 1 点备份/data/app
目录,保留 7 天历史版本,自动删除过期文件。
实现步骤:
-
创建备份脚本
/scripts/backup.sh
:#!/bin/bash DATE=$(date +%Y%m%d) BACKUP_DIR=/backup/app/${DATE} mkdir -p ${BACKUP_DIR} cp -r /data/app/* ${BACKUP_DIR} find /backup/app/ -type d -mtime +7 -exec rm -rf {} \; # 删除7天前的备份
-
赋予脚本执行权限
chmod +x /scripts/backup.sh
-
添加 crontab 任务:
crontab -e # 添加以下行(每天1点执行备份) 0 1 * * * /scripts/backup.sh
六、权限与安全:黑白名单与日志监控
6.1 黑白名单:精细化权限控制
-
at
权限控制:- 允许用户列表:
/etc/at.allow
(仅列出的用户可使用 at) - 禁止用户列表:
/etc/at.deny
(未列出的用户可使用 at)
示例:仅允许admin
和ops
用户使用 at:
echo "admin" > /etc/at.allow echo "ops" >> /etc/at.allow chmod 600 /etc/at.allow # 确保只有root可修改
- 允许用户列表:
-
crontab
权限控制:- 机制与 at 类似,控制文件为
/etc/cron.allow
和/etc/cron.deny
,常用于限制普通用户创建高危任务。
- 机制与 at 类似,控制文件为
6.2 日志监控:排查问题的关键
# 实时追踪任务执行日志
tail -f /var/log/cron | grep "CROND"
# 查看特定任务执行记录(如备份脚本)
grep "backup.sh" /var/log/cron
七、高级技巧:run-parts 批量管理脚本
7.1 什么是 run-parts?
run-parts
是 Linux 自带的脚本批量执行工具,可按字母顺序执行目录下的所有可执行文件,常用于管理同类任务(如系统定时任务目录/etc/cron.daily
)。
7.2 怎么用 run-parts?
场景:在每天 11 点执行/scripts
目录下的所有监控脚本。
操作步骤:
# 1. 创建脚本目录并添加文件
mkdir -p /scripts/monitor
touch /scripts/monitor/{cpu.sh,mem.sh,disk.sh}
# 赋予执行权限
chmod +x /scripts/monitor/* # 确保脚本可执行
# 2. 编辑系统crontab 调用run-parts
vim /etc/crontab
# 添加任务:每天11点执行目录下所有脚本(注意:run-parts会自动忽略非可执行文件)
0 11 * * * root run-parts /scripts/monitor
八、实战练习与答案(附排错思路)
练习 1:at 任务执行失败排查
问题:使用at now + 5 min
创建任务后,文件未生成。
排查步骤:
- 检查
atd
服务状态:systemctl status atd
(确保已启动) - 查看任务列表:
atq
(确认任务存在) - 检查日志:
tail /var/log/cron
(是否有权限错误,如创建文件需 root 权限)
练习 2:crontab 表达式调试
需求:每周一到周五的 9:00-17:00,每小时的第 10 分钟执行脚本。
正确表达式:
10 9-17 * * 1-5 /path/to/script.sh
练习 3:at 一次性任务
-
1 分钟后在 / 目录创建文件 at_test.txt
echo "touch /at_test.txt" | at now + 1 minutes
-
10:20 在所有终端显示 XXXXXXXXXX
at 10:20 tomorrow > wall "XXXXXXXXXX" > <Ctrl+D>
练习 4:crontab 周期性任务
-
每周一、三、日,凌晨 2-6 点每 30 分钟备份一次
crontab -e # 添加任务(注意周字段:0=日,1=一,3=三) */30 2-6 * * 0,1,3 echo "backup" >> /root/cron_back.log
-
每月 5、10、15、20 日,凌晨 0-6 点每 2 小时执行脚本
crontab -e 0 */2 5,10,15,20 * * /path/to/script.sh
九、注意事项与生产建议
- 时间格式验证:使用
crontab.guru
在线工具验证表达式正确性 - 权限控制:
- 脚本需赋予执行权限(
chmod +x
) - 避免使用 root 执行普通任务,建议创建专用用户
- 脚本需赋予执行权限(
- 日志记录:在脚本中添加日志输出,便于排查问题
# 示例脚本 #!/bin/bash DATE=$(date +"%Y-%m-%d %H:%M:%S") echo "[${DATE}] Backup started" >> /var/log/backup.log # 执行备份命令...
- 测试流程:
- 先使用
crontab -l
确认任务存在 - 通过
tail -f /var/log/cron
观察任务执行日志 - 生产环境建议先在测试环境验证无误后再部署
- 先使用
十、总结
本文全面解析了 Linux 计划任务的核心机制,从手动启动到系统调度,深入讲解了at
和crontab
的使用细节,包括时间格式、权限控制、实战练习等。掌握这些技能可极大提升服务器自动化管理效率,建议通过反复实验(至少 10 遍)加深理解,重点关注日志分析和权限管理,确保任务在生产环境中稳定运行。
作者简介:
一名大四的在校大学生,专注 Linux 系统优化与自动化r运维,擅长用图文结合解析技术原理。欢迎在评论区交流问题,或关注博主获取更多技术干货!