【Linux从入门到精通】第16篇:计划任务——让机器在半夜自动干活主要内容:crontab 语法格式详解(分时日月周);at 命令执行一次性任务;日志轮替(Logrotate)原理简述。
目录一、引言凌晨3点谁在替你工作二、crontab周期性任务的王者2.1 crontab是什么2.2 基础命令2.3 语法格式分时日月周2.4 实战示例2.5 新手最容易踩的三个坑2.6 排查crontab问题的方法三、系统级crontab/etc/crontab四、at一次性延迟任务4.1 基本用法4.2 时间格式4.3 管理at任务五、logrotate日志自动轮替5.1 为什么需要日志轮替5.2 logrotate是如何工作的5.3 配置文件结构5.4 验证与调试六、综合实战一个完整的运维自动化方案七、本篇小结动手练习八、下篇预告一、引言凌晨3点谁在替你工作凌晨3点你正在睡觉但服务器还在忙碌数据库正在备份日志正在归档证书正在续期报表正在生成。这些事当然不是有人半夜爬起来操作的——是计划任务在替你干活。Linux提供了两套任务调度机制机制适用场景特点crontab周期性重复任务精确到分钟最常用at一次性延迟任务简单直接临时使用systemd timer现代替代方案与systemd深度集成crontab是本文的重点另外两个作补充介绍。二、crontab周期性任务的王者2.1 crontab是什么crontabcron table是一个按时间表执行命令的系统。它由两部分组成cron守护进程crond在后台持续运行每分钟检查一次是否有任务到期crontab文件每个用户独立的任务时间表2.2 基础命令bashcrontab -l # 查看当前用户的所有定时任务 crontab -e # 编辑当前用户的定时任务 crontab -r # 删除当前用户的所有定时任务危险crontab -e是编辑crontab的唯一正确方式。不要直接编辑/var/spool/cron/下的文件因为直接编辑不会通知crond进程重新加载配置。2.3 语法格式分时日月周一条crontab任务的格式为五段式时间定义加执行命令text* * * * * 要执行的命令 ┬ ┬ ┬ ┬ ┬ │ │ │ │ └─── 星期 (0-70和7都代表周日) │ │ │ └────── 月份 (1-12) │ │ └────────── 日期 (1-31) │ └───────────── 小时 (0-23) └──────────────── 分钟 (0-59)时间字段的合法值字段范围特殊字符分钟0-59* , - /小时0-23* , - /日期1-31* , - /月份1-12* , - /星期0-70和7周日* , - /特殊字符详解符号含义示例解读*所有可能取值* * * * *每分钟执行,列举多个值0 2,14 * * *每天凌晨2点和下午2点-范围0 9-17 * * *每天9点到17点每小时整点/步进*/5 * * * *每5分钟执行一次2.4 实战示例每天凌晨3点备份数据库bash0 3 * * * /opt/scripts/backup_db.sh /var/log/backup.log 21每30分钟检查一次服务状态bash*/30 * * * * /opt/scripts/health_check.sh工作日周一至周五每小时的30分执行bash30 * * * 1-5 /opt/scripts/sync_data.sh每月1号凌晨2点清理旧日志bash0 2 1 * * find /var/log -name *.log -mtime 30 -delete每5分钟执行且只在上午9点到下午6点之间bash*/5 9-18 * * * /opt/scripts/monitor.sh每周日凌晨4点重启服务bash0 4 * * 0 systemctl restart myapp2.5 新手最容易踩的三个坑坑一环境变量crontab执行的命令使用一个极简的Shell环境PATH只有/usr/bin:/bin你的.bashrc和.profile不会被加载。如果你的脚本依赖自定义路径如/usr/local/bin下的工具有两种解决方法在脚本中显式使用绝对路径推荐bash/usr/local/bin/python3 /opt/scripts/backup.py或者在crontab文件开头定义环境变量bashPATH/usr/local/bin:/usr/bin:/bin MAILTOadminexample.com 0 3 * * * backup.sh坑二%号会被转义crontab中%是特殊字符表示换行。如果命令中包含%如date %Y%m%d需要用反斜杠转义bash0 3 * * * mysqldump mydb /backup/mydb_$(date \%Y\%m\%d).sql坑三重定向问题crontab默认会把命令的输出通过邮件发送给用户。如果系统没有配置邮件服务输出会丢失。建议始终显式重定向bash# 记录正常输出和错误输出 0 3 * * * /opt/scripts/backup.sh /var/log/backup.log 21 # 丢弃所有输出不适合调试阶段 0 3 * * * /opt/scripts/backup.sh /dev/null 212.6 排查crontab问题的方法如果crontab任务没有按预期执行按以下步骤排查bash# 1. 确认crond服务在运行 systemctl status crond # CentOS/RHEL systemctl status cron # Ubuntu/Debian # 2. 查看cron日志 grep CRON /var/log/syslog | tail -20 # Ubuntu/Debian grep CRON /var/log/cron | tail -20 # CentOS/RHEL # 3. 检查执行用户是否有脚本的执行权限 ls -l /opt/scripts/backup.sh # 4. 手动模拟cron环境执行命令最小环境变量 env -i /bin/bash --noprofile --norc # 在这个精简Shell中手动执行你的脚本观察报错三、系统级crontab/etc/crontab除了每个用户有自己的crontab系统还有全局的crontab文件/etc/crontab。它与用户crontab的区别在于多了个“用户”字段bash# /etc/crontab 格式 # 分 时 日 月 周 用户 命令 0 3 * * * root /opt/scripts/system_backup.sh系统预装的软件如logrotate会在这里或其子目录下安排定时任务。/etc/cron.d/目录下可以放置以文件形式存在的定时任务同样支持用户字段。此外还有按执行频率划分的目录目录执行频率/etc/cron.hourly/每小时/etc/cron.daily/每天/etc/cron.weekly/每周/etc/cron.monthly/每月把脚本放入这些目录即可自动运行不需要手动编辑crontab。四、at一次性延迟任务crontab解决“每隔多久做一次”at解决“在某个特定时间点做一次”。4.1 基本用法bash# 安装at部分发行版默认不装 sudo apt install at -y # Ubuntu/Debian sudo dnf install at -y # CentOS/RHEL # 启动atd服务 sudo systemctl enable --now atd执行一次性任务bash# 交互式输入at 时间然后输入要执行的命令CtrlD结束 at 02:30 warning: commands will be executed using /bin/sh at /opt/scripts/upgrade.sh at CtrlD job 3 at Sat Apr 25 02:30:00 2026 # 一行命令完成 echo /opt/scripts/upgrade.sh | at 02:30 # 直接用管道传入命令 at 02:30 -f /opt/scripts/upgrade.sh4.2 时间格式at支持丰富的时间表达bashat now 5 minutes # 5分钟后 at now 2 hours # 2小时后 at now 3 days # 3天后 at 10:00 AM tomorrow # 明天上午10点 at 23:00 Friday # 本周五晚上11点 at midnight # 午夜4.3 管理at任务bashatq # 查看待执行的at任务队列 at -c 任务编号 # 查看某项任务的具体内容 atrm 任务编号 # 删除某项任务五、logrotate日志自动轮替5.1 为什么需要日志轮替前几篇文章我们反复提到/var/log它是磁盘占满的头号嫌疑犯。如果不加控制一个服务的日志文件可以无限增长最终撑爆磁盘。logrotate就是为解决这个问题而生的——它定期对日志文件执行轮替rotation把旧日志压缩归档删除超过保留期限的日志保持当前日志文件在合理大小。5.2 logrotate是如何工作的logrotate是通过cron触发执行的。查看bashcat /etc/cron.daily/logrotate现代系统中logrotate可能通过systemd timer触发bashsystemctl list-timers | grep logrotate5.3 配置文件结构主配置文件/etc/logrotate.conf服务专用配置/etc/logrotate.d/目录下的独立文件以Nginx日志为例/etc/logrotate.d/nginxtext/var/log/nginx/*.log { weekly # 每周轮替一次 rotate 52 # 保留52个归档约一年 missingok # 日志文件不存在也不报错 notifempty # 日志为空则不轮替 compress # 压缩归档文件节省空间 delaycompress # 延迟一次压缩保留最近一个归档不压缩方便查看 sharedscripts # 所有日志轮替完才执行postrotate postrotate [ -f /var/run/nginx.pid ] kill -USR1 cat /var/run/nginx.pid endscript }关键参数解读参数含义daily/weekly/monthly轮替周期rotate N保留最近N个归档文件size 100M日志超过指定大小即轮替与时间条件取“或”关系compress用gzip压缩归档后缀.gzmissingok日志文件不存在时不报错copytruncate复制后清空原文件用于不支持信号重读的服务postrotate/endscript轮替后执行的脚本如让服务重新打开日志文件5.4 验证与调试bash# 测试配置是否有效模拟执行不实际修改 sudo logrotate -d /etc/logrotate.conf # 强制执行轮替用于验证配置是否生效 sudo logrotate -f /etc/logrotate.conf # 只测试特定服务的配置 sudo logrotate -d /etc/logrotate.d/nginx六、综合实战一个完整的运维自动化方案假设你需要管理一个Web应用设计自动化方案要求每天凌晨3点备份数据库每30分钟检查服务是否存活每周清理一次30天前的临时文件日志自动轮替保留两个月第一步编写备份脚本bashsudo vim /opt/scripts/backup.shbash#!/bin/bash mysqldump -u root mydb /backup/mydb_$(date %Y%m%d).sql find /backup -name *.sql -mtime 7 -delete # 只保留7天的备份bashchmod x /opt/scripts/backup.sh第二步编写健康检查脚本bashsudo vim /opt/scripts/health_check.shbash#!/bin/bash if ! curl -s http://localhost/health /dev/null; then echo $(date): Service down, restarting... /var/log/health_check.log systemctl restart myapp fi第三步配置crontabbashcrontab -etext# 每天凌晨3点备份 0 3 * * * /opt/scripts/backup.sh /var/log/backup.log 21 # 每30分钟健康检查 */30 * * * * /opt/scripts/health_check.sh # 每周日凌晨2点清理临时文件 0 2 * * 0 find /tmp -type f -mtime 30 -delete第四步配置日志轮替bashsudo vim /etc/logrotate.d/myapptext/var/log/myapp/*.log { daily rotate 60 missingok notifempty compress delaycompress copytruncate }第五步验证bash# 验证crontab语法 crontab -l # 手动测试脚本 /opt/scripts/backup.sh /opt/scripts/health_check.sh # 验证logrotate配置 sudo logrotate -d /etc/logrotate.d/myapp七、本篇小结crontab核心语法text分 时 日 月 周 命令* 所有取值, 列举- 范围/ 步进编辑用crontab -e查看用crontab -l三大坑环境变量精简、%号需转义、输出需重定向at一次性任务at 时间交互式输入CtrlD结束atq查看队列atrm删除logrotate日志轮替通过cron或systemd timer触发配置在/etc/logrotate.d/下compressrotate N控制归档策略动手练习bash# 1. 查看自己的crontab crontab -l # 2. 添加一个测试任务每分钟写入时间戳到文件 crontab -e # 添加* * * * * date /tmp/cron_test.log # 2分钟后检查结果 cat /tmp/cron_test.log # 3. 记得删除测试任务 crontab -e # 删除刚才添加的行 # 4. 练习at命令 at now 2 minutes at echo Hello from at /tmp/at_test.log # CtrlD atq # 查看待执行任务 # 2分钟后检查 cat /tmp/at_test.log # 5. 查看logrotate配置 ls /etc/logrotate.d/ cat /etc/logrotate.d/nginx 2/dev/null || cat /etc/logrotate.d/rsyslog八、下篇预告计划任务产生的日志加上系统运行产生的日志构成了Linux的“黑匣子”——/var/log。当系统出问题时日志是排查的第一手资料。下一篇我们将深入日志系统学习/var/log/messages、secure、dmesg各记录什么内容journalctl工具的高级过滤技巧如何看懂内核报错信息你将掌握从海量日志中快速定位问题线索的方法。延伸思考crontab -e与直接vim /var/spool/cron/用户名有什么区别前者会在编辑完成后自动通知crond重新加载配置后者不会。这就是为什么“编辑crontab要用crontab -e”是铁律。类似的“专用编辑工具”还有visudo编辑sudoers和vipw编辑passwd它们都会在编辑完成后检查语法防止配置错误导致系统异常。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2551157.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!