Linux定时任务与自动化脚本实战

前言

服务器运维离不开定时任务:日志清理、数据备份、监控告警、报表生成……手动执行既繁琐又容易遗漏。crontab是Linux下最常用的定时任务工具,配合shell脚本可以实现各种自动化需求。

本文整理crontab的使用技巧和常见自动化脚本,附带踩坑经验。


1. crontab基础

1.1 基本语法

* * * * * command │ │ │ │ │ │ │ │ │ └── 星期(0-7,0和7都是周日) │ │ │ └──── 月份(1-12) │ │ └────── 日期(1-31) │ └──────── 小时(0-23) └────────── 分钟(0-59)

1.2 常用时间表达式

# 每分钟执行* * * * * /path/to/script.sh# 每小时整点执行0* * * * /path/to/script.sh# 每天凌晨2点执行02* * * /path/to/script.sh# 每周一凌晨3点执行03* *1/path/to/script.sh# 每月1号凌晨4点执行041* * /path/to/script.sh# 每5分钟执行*/5 * * * * /path/to/script.sh# 每天8点到18点,每小时执行08-18 * * * /path/to/script.sh# 工作日每天9点执行09* *1-5 /path/to/script.sh# 每天凌晨1点和13点执行01,13* * * /path/to/script.sh

1.3 crontab管理命令

# 编辑当前用户的crontabcrontab-e# 查看当前用户的crontabcrontab-l# 删除当前用户的crontabcrontab-r# 编辑指定用户的crontab(需要root权限)crontab-u username -e# 从文件导入crontabcrontab/path/to/crontab.txt

2. crontab踩坑指南

2.1 环境变量问题

crontab执行环境和交互式shell不同,PATH很精简:

# 错误:直接写命令名* * * * * mysql -e"select 1"# 正确:使用绝对路径* * * * * /usr/bin/mysql -e"select 1"# 或者在脚本开头设置PATH#!/bin/bashexportPATH=/usr/local/bin:/usr/bin:/bin

查看crontab的环境变量

# 创建一个临时任务* * * * *env>/tmp/cron_env.txt

2.2 输出处理

默认情况下,crontab会把输出发到用户邮箱:

# 丢弃所有输出* * * * * /path/to/script.sh>/dev/null2>&1# 只记录错误* * * * * /path/to/script.sh>/dev/null2>>/var/log/cron_error.log# 记录所有输出* * * * * /path/to/script.sh>>/var/log/cron.log2>&1# 记录输出并带时间戳* * * * * /path/to/script.sh2>&1|whilereadline;doecho"$(date):$line";done>>/var/log/cron.log

2.3 特殊字符转义

# 错误:%在crontab中是换行符02* * * /bin/date +%Y%m%d# 正确:转义%02* * * /bin/date +\%Y\%m\%d# 或者放到脚本里执行02* * * /path/to/backup.sh

2.4 执行权限

# 脚本需要可执行权限chmod+x /path/to/script.sh# 或者用bash显式执行* * * * * /bin/bash /path/to/script.sh

2.5 工作目录

# crontab默认工作目录是用户home# 脚本中使用相对路径可能出问题# 解决:在脚本开头切换目录#!/bin/bashcd/path/to/workdir||exit1

3. 实用自动化脚本

3.1 日志清理脚本

#!/bin/bash# clean_logs.sh - 清理过期日志LOG_DIRS=("/var/log/app""/data/logs/nginx""/data/logs/tomcat")KEEP_DAYS=30fordirin"${LOG_DIRS[@]}";doif[-d"$dir"];thenecho"清理目录:$dir"find"$dir"-name"*.log"-mtime +$KEEP_DAYS-deletefind"$dir"-name"*.log.gz"-mtime +$KEEP_DAYS-delete# 清理空目录find"$dir"-type d -empty -delete2>/dev/nullfidone# 清理系统日志journalctl --vacuum-time=${KEEP_DAYS}d2>/dev/nullecho"日志清理完成:$(date)"

crontab配置:

# 每天凌晨3点清理日志03* * * /opt/scripts/clean_logs.sh>>/var/log/clean_logs.log2>&1

3.2 数据库备份脚本

#!/bin/bash# mysql_backup.sh - MySQL备份MYSQL_USER="backup"MYSQL_PASS="your_password"BACKUP_DIR="/data/backup/mysql"KEEP_DAYS=7DATE=$(date+%Y%m%d_%H%M%S)# 创建备份目录mkdir-p"$BACKUP_DIR"# 获取所有数据库databases=$(mysql -u"$MYSQL_USER"-p"$MYSQL_PASS"-e"SHOW DATABASES;"|grep-Ev"(Database|information_schema|performance_schema|sys)")fordbin$databases;doecho"备份数据库:$db"mysqldump -u"$MYSQL_USER"-p"$MYSQL_PASS"\--single-transaction\--routines\--triggers\"$db"|gzip>"$BACKUP_DIR/${db}_${DATE}.sql.gz"done# 清理过期备份find"$BACKUP_DIR"-name"*.sql.gz"-mtime +$KEEP_DAYS-delete# 统计备份大小echo"备份完成,总大小:$(du-sh $BACKUP_DIR|cut-f1)"

3.3 磁盘空间监控脚本

#!/bin/bash# disk_monitor.sh - 磁盘空间监控THRESHOLD=80ALERT_EMAIL="admin@example.com"# 获取磁盘使用率df-h|awk'NR>1 {print $5,$6}'|whilereadusagemount;do# 去掉百分号usage_num=${usage%\%}if["$usage_num"-gt"$THRESHOLD"];thenmessage="警告:$mount磁盘使用率$usage超过阈值${THRESHOLD}%"echo"$message"# 发送告警(可选)# echo "$message" | mail -s "磁盘告警 - $(hostname)" $ALERT_EMAIL# 或者发送到钉钉/企业微信# curl -X POST "https://webhook.url" -d "{\"text\":\"$message\"}"fidone

3.4 服务健康检查脚本

#!/bin/bash# service_check.sh - 服务健康检查SERVICES=("nginx:80""mysql:3306""redis:6379""app:8080")check_port(){localname=$1localport=$2ifnc-z localhost$port2>/dev/null;thenecho"[OK]$name(port$port)"return0elseecho"[FAIL]$name(port$port)"return1fi}forservicein"${SERVICES[@]}";doname=${service%:*}port=${service#*:}if!check_port"$name""$port";then# 尝试重启服务echo"尝试重启$name..."systemctl restart$name2>/dev/nullsleep5if!check_port"$name""$port";thenecho"重启失败,发送告警"# 发送告警逻辑fifidone

3.5 SSL证书到期检查

#!/bin/bash# ssl_check.sh - SSL证书到期检查DOMAINS=("www.example.com""api.example.com")WARN_DAYS=30fordomainin"${DOMAINS[@]}";do# 获取证书到期时间expiry_date=$(echo|openssl s_client -servername"$domain"-connect"$domain:443"2>/dev/null|\openssl x509 -noout -enddate2>/dev/null|cut-d=-f2)if[-z"$expiry_date"];thenecho"[ERROR] 无法获取$domain证书信息"continuefi# 计算剩余天数expiry_epoch=$(date-d"$expiry_date"+%s)current_epoch=$(date+%s)days_left=$(((expiry_epoch-current_epoch)/86400))if[$days_left-lt$WARN_DAYS];thenecho"[WARN]$domain证书将在$days_left天后过期"elseecho"[OK]$domain证书剩余$days_left天"fidone

4. 多服务器定时任务管理

4.1 问题场景

当管理多台服务器时,定时任务分散在各机器上,维护起来很麻烦:

  • 修改任务要逐台登录
  • 不知道哪台机器上有什么任务
  • 任务执行情况难以统计

4.2 集中管理方案

方案一:Ansible管理crontab

# crontab.yml-hosts:alltasks:-name:部署日志清理任务cron:name:"clean logs"minute:"0"hour:"3"job:"/opt/scripts/clean_logs.sh >> /var/log/clean_logs.log 2>&1"-name:部署磁盘监控任务cron:name:"disk monitor"minute:"*/10"job:"/opt/scripts/disk_monitor.sh"

执行:

ansible-playbook -i inventory crontab.yml

方案二:集中式任务调度

使用专门的任务调度系统:

  • XXL-JOB
  • Airflow
  • Jenkins Pipeline

这些系统可以集中管理所有服务器的定时任务,还有执行日志、失败重试、依赖调度等功能。

4.3 跨网络批量管理

如果服务器分布在不同网络环境(办公室、家里、云服务器),Ansible连接就比较麻烦。

常见解决方案:

  1. 跳板机:所有机器都能连接的中转服务器
  2. VPN:把所有机器组到一个网络
  3. 组网工具:WireGuard、ZeroTier、星空组网等,配置简单,把机器串成虚拟局域网

用组网工具的好处是配置一次后,后续直接用内网IP管理,不用关心机器实际在哪个网络。Ansible的inventory直接写虚拟IP就行:

# inventory [web] 10.10.0.1 10.10.0.2 [db] 10.10.0.10

5. 任务执行监控

5.1 记录任务执行日志

#!/bin/bash# 通用任务包装器# usage: task_wrapper.sh <task_name> <command>TASK_NAME=$1shiftCOMMAND="$@"LOG_DIR="/var/log/cron_tasks"LOG_FILE="$LOG_DIR/${TASK_NAME}.log"mkdir-p"$LOG_DIR"START_TIME=$(date'+%Y-%m-%d %H:%M:%S')echo"[$START_TIME] 开始执行:$TASK_NAME">>"$LOG_FILE"# 执行任务OUTPUT=$($COMMAND2>&1)EXIT_CODE=$?END_TIME=$(date'+%Y-%m-%d %H:%M:%S')DURATION=$SECONDSecho"$OUTPUT">>"$LOG_FILE"echo"[$END_TIME] 执行完成,退出码:$EXIT_CODE,耗时:${DURATION}秒">>"$LOG_FILE"echo"---">>"$LOG_FILE"# 如果失败,发送告警if[$EXIT_CODE-ne0];thenecho"任务失败:$TASK_NAME, 退出码:$EXIT_CODE"# 告警逻辑fiexit$EXIT_CODE

使用方式:

# crontab02* * * /opt/scripts/task_wrapper.sh mysql_backup /opt/scripts/mysql_backup.sh

5.2 任务执行统计

#!/bin/bash# task_stats.sh - 统计任务执行情况LOG_DIR="/var/log/cron_tasks"echo"=== 任务执行统计 ==="echo""forlogin"$LOG_DIR"/*.log;dotask_name=$(basename"$log".log)# 统计成功/失败次数total=$(grep-c"执行完成""$log"2>/dev/null||echo0)success=$(grep"退出码: 0""$log"|wc-l)failed=$((total-success))# 最后执行时间last_run=$(grep"开始执行""$log"|tail-1|grep-oP'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}')printf"%-20s 总计: %-5s 成功: %-5s 失败: %-5s 最后执行: %s\n"\"$task_name""$total""$success""$failed""$last_run"done

6. 高级技巧

6.1 防止任务重复执行

#!/bin/bash# 使用flock防止重复执行LOCK_FILE="/tmp/my_task.lock"exec200>"$LOCK_FILE"flock -n200||{echo"任务正在执行中,退出"exit1}# 正常的任务逻辑echo"开始执行..."sleep60echo"执行完成"

或者在crontab中直接使用:

* * * * * flock -n /tmp/my_task.lock /path/to/script.sh

6.2 任务超时控制

# 使用timeout命令限制执行时间* * * * *timeout300/path/to/script.sh# 超时后发送SIGKILL* * * * *timeout-k10300/path/to/script.sh

6.3 随机延迟启动

避免所有机器同时执行任务(比如同时访问某个API):

#!/bin/bash# 随机延迟0-300秒sleep$((RANDOM%300))# 执行实际任务/path/to/actual_script.sh

6.4 任务依赖

#!/bin/bash# 先执行备份,成功后再清理/opt/scripts/mysql_backup.sh&&/opt/scripts/clean_old_backup.sh

更复杂的依赖关系建议用专门的调度系统。


7. systemd timer替代方案

systemd timer是crontab的现代替代:

# /etc/systemd/system/backup.service [Unit] Description=MySQL Backup [Service] Type=oneshot ExecStart=/opt/scripts/mysql_backup.sh
# /etc/systemd/system/backup.timer [Unit] Description=Run backup daily [Timer] OnCalendar=*-*-* 02:00:00 Persistent=true [Install] WantedBy=timers.target

启用:

systemctlenablebackup.timer systemctl start backup.timer# 查看所有timersystemctl list-timers

systemd timer优点

  • 日志集成到journalctl
  • 支持更复杂的时间表达式
  • 可以设置资源限制
  • 错过的任务可以补执行(Persistent=true)

总结

场景crontab表达式
每分钟* * * * *
每5分钟*/5 * * * *
每小时0 * * * *
每天凌晨2点0 2 * * *
每周一9点0 9 * * 1
每月1号0 0 1 * *
工作日0 9 * * 1-5

最佳实践

  1. 使用绝对路径:脚本和命令都用绝对路径
  2. 处理输出:重定向到日志文件,避免邮件堆积
  3. 防止重复:使用flock防止任务重叠
  4. 超时控制:长任务加timeout限制
  5. 监控告警:记录执行日志,失败时告警
  6. 集中管理:多服务器用Ansible或调度系统统一管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1124767.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

零基础转行Java开发,学习路线推荐!

现在IT整体大环境不好&#xff0c;该怎么提升自己的核心竞争力&#xff1f;需要储备一些什么技术才能在Java立足呢&#xff1f;如果你对此没啥概念&#xff0c;毫无方向&#xff0c;不妨来看看阿里最新出品的P5~P7架构师学习路线&#xff0c;按着路线学习&#xff0c;技术上你能…

身份证二要素验证接口对接中常见问题汇总

在实际业务系统中接入身份证二要素验证接口(姓名 身份证号一致性校验)时&#xff0c;大多数问题并不来源于接口能力本身&#xff0c;而是集中出现在参数传递、签名生成、权限配置以及调用环境等细节上。 新诺韦尔从技术支持视角出发&#xff0c;结合接口文档规范与真实对接经…

AI悖论:技术迷雾中的人类抉择

当人工智能&#xff08;AI&#xff09;以前所未有的速度渗透进社会经济的每一个角落&#xff0c;一系列深刻的矛盾也随之浮现。这些悖论并非源于技术本身的缺陷&#xff0c;而是人类在开发、应用AI过程中&#xff0c;自身需求、认知与价值取向的集中投射。从就业格局到生产率变…

展望2026:出版业融合发展的深度观察与未来图景

当数字化浪潮席卷而来,出版业正站在一个前所未有的转折点上。2021至2024年,出版融合发展累计收入达358.62亿元,2024年单年收入97.24亿元,同比增长6.32%。这些数字背后,是一个传统行业在数字时代的艰难转身,也是一场关乎文化传承与创新的深刻变革。当我们将目光投向2026年,出版业…

2026年最新爆火!9款免费AI论文工具限时公开,一键生成初稿告别熬夜!

为什么你必须立刻行动&#xff1f;——论文冲刺的“最后72小时”危机 2026年的毕业季&#xff0c;比以往任何时候都更残酷&#xff1a; 答辩倒计时只剩最后3天&#xff0c;而你的论文还停留在框架阶段&#xff1b;导师凌晨发来修改意见&#xff0c;措辞严厉&#xff0c;暗示“…

Java之构造方法

什么是构造方法&#xff1f;构造方法是 Java 中一种特殊的方法&#xff0c;它的核心作用是&#xff1a;在创建对象&#xff08;使用new关键字&#xff09;时&#xff0c;初始化该对象的成员变量构造方法解决什么问题&#xff1f;构造方法解决给对象初始化的问题构造方法怎么使用…

‌性能测试认证备考全指南:从ISTQB到AI驱动的云原生实战

‌一、主流性能测试认证体系全景图‌认证体系认证级别适用人群核心考试内容权威性与行业认可度‌ISTQB Performance Testing‌基础级&#xff08;FL&#xff09;、进阶级&#xff08;AT&#xff09;、专家级&#xff08;ET&#xff09;初级测试员、测试经理、质量负责人七大知识…

mysql innodb_log_buffer_size 参数详解

innodb_log_buffer_size 是 MySQL InnoDB 存储引擎中的一个重要配置参数&#xff0c;用于控制 InnoDB 日志缓冲区&#xff08;log buffer&#xff09;的大小。这个缓冲区用于在将事务日志&#xff08;redo log&#xff09;写入磁盘之前&#xff0c;临时缓存这些日志数据。一、作…

前沿制造深度:传统系统如OEE是否有必要使用AI技术改造?

今天是2026年1月7日。欢迎来到《前沿智造》深度访谈节目。我是主持人闻道瑞伟。 制造业的数字化转型已进入深水区,和所有传统的制造运营绩效指标体系和数字化系统一样,作为衡量生产效能的“黄金指标”——整体设备效率系统,正站在一个技术十字路口。一边是运行多年、稳定但…

mysql innodb_flush_log_at_trx_commit 参数详解

innodb_flush_log_at_trx_commit 是 MySQL InnoDB 存储引擎中控制事务提交时 redo log&#xff08;重做日志&#xff09;刷盘行为的关键参数&#xff0c;直接影响 数据持久性 与 写入性能 之间的权衡。一、参数作用 该参数决定了&#xff1a;当一个事务执行 COMMIT 时&#xff…

救命神器!研究生必备10个AI论文平台深度测评

救命神器&#xff01;研究生必备10个AI论文平台深度测评 一、不同维度核心推荐&#xff1a;10款AI工具各有所长 对于研究生而言&#xff0c;学术写作是一个复杂而繁琐的过程&#xff0c;从开题到初稿、查重、降重再到排版&#xff0c;每个环节都需要合适的工具来辅助。不同的AI…

‌2026年安全测试工具Top 10:AI驱动下的范式跃迁与从业者实战指南

一、2026年安全测试工具演进的底层逻辑‌2026年不再是“工具功能叠加”的时代&#xff0c;而是‌智能体&#xff08;Agent&#xff09;主导测试流程‌的元年。Gartner与Forrester在2025年报告中已明确指出&#xff1a;“AI在安全测试中的角色&#xff0c;已从‘辅助脚本生成’升…

2026年AI论文工具爆火!9款神器限时公开,从选题到降重一站式搞定

凌晨3点&#xff0c;导师的修改意见邮件第5次响起&#xff0c;查重率卡在29.9%&#xff0c;deadline只剩48小时……这样的至暗时刻&#xff0c;你还在独自硬扛吗&#xff1f;醒醒&#xff0c;2026年的学术圈&#xff0c;早已不是一个人的战场&#xff01; 深夜赶稿、反复修改、…

从600万到3000万:揭秘中小商家的增长密码

引言 中小商家最头疼的问题&#xff1a;产品不错&#xff0c;但没钱做推广。 今天看更关键的部分——如何从600万做到3000万。这背后不是靠运气&#xff0c;而是一套可复制的商业架构。 一、传统生意困局&#xff1a;酒香也怕巷子深 大多数商家面临三重困境&#xff1a; 广告…

Java之匿名对象

有名对象&#xff1a;有名字的对象 Student stu new Student(); //有名字的对象//对象名&#xff1a; stu匿名对象&#xff1a;创建的对象没有名字 new Student(); //创建的对象没有名字 new Student("张三",23);匿名对象的使用方式 匿名对象可以像有名对象一样使用…

基于Springboot + vue3实现的家具商城系统

项目描述本系统包含管理员和用户两个角色。管理员角色&#xff1a;轮播图管理&#xff1a;管理轮播图配置参数。管理员管理&#xff1a;管理系统中的管理员信息&#xff0c;包括添加、删除和修改管理员。用户管理&#xff1a;管理系统中的用户信息&#xff0c;包括添加、删除和…

CTF入门指南:从零到拿下Flag的完整路径

&#x1f4da; 首先&#xff0c;正确认识CTFCTF&#xff08;Capture The Flag&#xff0c;夺旗赛&#xff09;是网络安全的“实战练兵场”。你需要通过挖掘漏洞、解密数据、逆向分析程序等手段&#xff0c;找到隐藏的特定字符串&#xff08;Flag&#xff0c;通常格式为flag{xxx…

免费文献检索网站推荐:实用高效的学术资源获取平台

一、WisPaper&#xff1a;智能学术搜索激发科研灵感 科研创新的关键是了解前沿&#xff0c;找到突破口。但传统查文献方式往往效率低&#xff1a; Google Scholar 或 arXiv 搜索结果太多&#xff0c;难以筛选公众号推送滞后&#xff0c;容易错过最新研究文献阅读时间长&#…

西门子PLC STL编程常见的错误(四):上升(下降)沿不工作

上升(下降)沿不工作也是一种常见的错误&#xff0c;尽管手册中“P”或“N”指令允许的数据类型为:I&#xff0c;Q&#xff0c;M&#xff0c;L&#xff0c;D。但如果没有特殊目的&#xff0c;仅建议使用M及DB数据类型。如下图: 西门子“P”指令要求使用与前面指令不相同的地址&…

【Java毕设源码分享】基于springboot+vue的OA管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…