—title: 10 个实用的 Shell 脚本 — 日常运维必备date: 2026-06-26tags: [shell, 运维, 自动化]series: CSDN知识付费—# 10 个实用的 Shell 脚本 — 日常运维必备在 Linux 运维的日常工作中Shell 脚本是程序员和运维工程师最趁手的瑞士军刀。无论是批量处理日志、监控系统状态还是自动化部署一个得力的脚本往往能让你从重复劳动中解放出来。然而很多新人要么不会写要么写出的脚本缺乏健壮性容易在生产环境翻车。今天我整理了 10 个日常运维必背的 Shell 脚本覆盖文件管理、系统监控、网络检测、备份、自动化巡检等高频场景。每个脚本都附带详细注释你可以直接拿去用也可以稍加改造适配你的环境。 建议收藏本文遇到运维需求时可以回来抄作业。—## 脚本一批量重命名文件基于正则场景将目录下所有.jpg文件改为yyyy-MM-dd_xxx.jpg格式便于归档。bash#!/bin/bash# 批量重命名在文件名前插入日期前缀# 用法./rename.sh /path/to/imagesTARGET_DIR${1:-.} # 默认当前目录DATE_TAG$(date %Y-%m-%d) # 获取当前日期cd $TARGET_DIR || { echo 目录不存在; exit 1; }for file in *.jpg; do # 跳过没有匹配的文件 [ -f $file ] || continue # 新文件名 日期_原文件名 mv -v $file ${DATE_TAG}_${file}doneecho 重命名完成踩坑提醒一定要先[ -f $file ] || continue否则当目录下没有.jpg文件时$file会变成字面量*.jpg导致把文件改名为奇怪的名字。—## 脚本二自动清理 7 天前的日志文件场景/var/log/myapp/每天产生大量日志磁盘空间告警。bash#!/bin/bash# 自动清理过期日志并记录清理动作LOG_DIR/var/log/myappRETENTION_DAYS7CLEANUP_LOG/var/log/cleanup_history.log# find -mtime 7 表示修改时间超过 7 天的文件find $LOG_DIR -type f -name *.log -mtime $RETENTION_DAYS -exec rm -f {} \;# 记录清理结果echo $(date %Y-%m-%d %H:%M:%S) 清理了 $LOG_DIR 中 $RETENTION_DAYS 天前的日志文件 $CLEANUP_LOG进阶用法配合crontab每天凌晨执行bash0 2 * * * /usr/local/bin/cleanup_logs.sh—## 脚本三服务器资源监控CPU、内存、磁盘场景运维需要快速查看当前系统负载但不想记住一堆命令。bash#!/bin/bash# 一键系统资源概览echo 系统资源报告 $(date) # CPU 负载最近 1 分钟echo 【CPU 负载】uptime | awk -Fload average: {print $2}# 内存使用总量、已用、可用、百分比echo 【内存使用】free -h | awk /^Mem:/ {print 已用: $3 / 总量: $2 / 可用: $7}# 磁盘使用率超过 80% 用红色提醒echo 【磁盘使用】df -h | grep -E ^/dev/ | while read line; do usage$(echo $line | awk {print $5} | sed s/%//) if [ $usage -gt 80 ]; then echo -e \033[31m⚠️ $line\033[0m # 红色 else echo $line fidone实用技巧用颜色输出更容易发现问题\033[31m是红色\033[0m是恢复默认。—## 脚本四批量检查网络连通性场景运维接手多台服务器需要快速排查哪些机器网络不通。bash#!/bin/bash# 批量 Ping 检测支持超时和并行IP_LIST192.168.1.1192.168.1.10192.168.1.20google.comTIMEOUT3check_ip() { local ip$1 if ping -c 1 -W $TIMEOUT $ip /dev/null; then echo ✅ $ip 可达 else echo ❌ $ip 不可达 fi}for ip in $IP_LIST; do # 放入后台并行执行大大加快速度 check_ip $ip done# 等待所有后台任务完成waitecho 检查完毕。性能对比如果 10 个 IP 串行检查每个 3 秒超时最多耗时 30 秒。改用并行后基本在 3 秒内完成。—## 脚本五数据库自动备份MySQL场景每天凌晨备份生产数据库保留最近 7 天数据。bash#!/bin/bash# MySQL 全量备份脚本DB_USERbackup_userDB_PASSyour_passwordDB_NAMEproduction_dbBACKUP_DIR/data/backup/mysqlDATE_TAG$(date %Y-%m-%d_%H%M)# 如果目录不存在则创建mkdir -p $BACKUP_DIR# 执行备份压缩存储mysqldump -u$DB_USER -p$DB_PASS --single-transaction \ --routines --triggers $DB_NAME \ | gzip ${BACKUP_DIR}/${DB_NAME}_${DATE_TAG}.sql.gz# 删除 7 天前的备份find $BACKUP_DIR -type f -name *.sql.gz -mtime 7 -deleteecho ✅ 备份完成${BACKUP_DIR}/${DB_NAME}_${DATE_TAG}.sql.gz关键参数解释---single-transaction用于 InnoDB 表保证备份一致性而不锁表---routines--triggers导出存储过程和触发器—## 脚本六检测登录失败并封禁 IP场景防止 SSH 暴力破解自动将失败次数过多的 IP 加入 iptables 黑名单。bash#!/bin/bash# 基于 /var/log/secure 检测失败登录动态封禁THRESHOLD5BLOCK_TIME3600 # 秒LOG_FILE/var/log/secure# 提取失败 IP统计次数grep Failed password $LOG_FILE | grep -oP from \K[0-9.] | sort | uniq -c | while read count ip; do if [ $count -ge $THRESHOLD ]; then # 检查是否已被封禁 if ! iptables -L INPUT -n | grep -q $ip; then iptables -A INPUT -s $ip -j DROP echo $(date) 封禁 $ip 失败次数$count /var/log/block_ip.log fi fidone注意生产环境建议用fail2ban这里提供的是轻量级替代方案。iptables 规则重启后会丢失需要配合iptables-save持久化。—## 脚本七目录同步与差异备份rsync场景将 Web 静态文件从生产服务器同步到备份服务器。bash#!/bin/bash# 增量同步目录并保留 7 天历史SOURCE/data/wwwTARGETbackup192.168.1.100:/backup/wwwEXCLUDE_FILE/etc/rsync_exclude.txt # 排除 node_modules, .git 等# 增量同步删除源端不存在的文件rsync -avz --delete --exclude-from$EXCLUDE_FILE \ $SOURCE $TARGET# 快照备份每天保留一份完整副本保留最近 7 天# 这里用了 hardlink 节省空间实际生产推荐 rsnapshotDATE_TAG$(date %Y-%m-%d)BACKUP_BASE/data/snapshotmkdir -p $BACKUP_BASE/$DATE_TAGcp -al $SOURCE $BACKUP_BASE/$DATE_TAG# 删除 7 天前的快照find $BACKUP_BASE -maxdepth 1 -type d -mtime 7 -exec rm -rf {} \;关键点cp -al创建的是硬链接不会占用额外磁盘空间但实现了每天一份完整备份的假象。这是低成本快照的经典做法。—## 脚本八定时检测进程异常则自动重启场景某 Java 服务偶尔内存溢出挂掉需自动守护重启。bash#!/bin/bash# 进程保活脚本配合 crontab 每分钟执行PROCESS_NAMEjava -jar myapp.jarPID_FILE/var/run/myapp.pidSTART_CMD/usr/local/myapp/start.sh# 检查进程是否存在if ! pgrep -f $PROCESS_NAME /dev/null 21; then echo $(date) 进程 ${PROCESS_NAME} 已挂尝试重启... /var/log/keepalive.log $START_CMD # 等待几秒检查是否启动成功 sleep 5 if pgrep -f $PROCESS_NAME /dev/null 21; then echo 重启成功 /var/log/keepalive.log else echo 重启失败请人工介入 /var/log/keepalive.log fifi性能优化尽量不要频繁pgrep整个命令行对于已知 PID 的服务直接用kill -0 $PID检查效率更高。但对于启动脚本不明的情况pgrep -f是通用方案。—## 脚本九快速生成系统巡检报告场景每天生成一份 HTML 报告展示服务器的核心指标。bash#!/bin/bash# 生成系统巡检 HTML 报告REPORT_DIR/var/www/reportsHTML_FILE${REPORT_DIR}/report_$(date %Y%m%d).htmlmkdir -p $REPORT_DIR# 采集数据HOSTNAME$(hostname)UPTIME$(uptime -p)DISK$(df -h / | tail -1 | awk {print $4 可用共$2})# 生成 HTMLcat $HTML_FILE EOF!DOCTYPE htmlhtmlheadtitle系统巡检 - $HOSTNAME/title/headbodyh1巡检报告$HOSTNAME/h1p生成时间$(date %Y-%m-%d %H:%M)/ph2运行时长/h2p$UPTIME/ph2磁盘剩余/h2p$DISK/ph2内存使用/h2pre$(free -h)/pre/body/htmlEOFecho 报告已生成$HTML_FILE锦上添花加上表格、图表库如 ECharts或者直接在微信/钉钉推送告警。—## 脚本十一键部署 Nginx 配置检查场景新服务器初始化快速搭建 Web 服务。bash#!/bin/bash# 自动安装 Nginx 并检查配置set -e # 任何错误即退出if [ $EUID -ne 0 ]; then echo 请使用 root 或 sudo 执行 exit 1fi# 检测包管理器if command -v apt /dev/null; then apt update apt install -y nginxelif command -v yum /dev/null; then yum install -y epel-release yum install -y nginxelse echo 不支持的 Linux 发行版; exit 1fi# 启动并设置开机自启systemctl enable --now nginx# 配置语法检查nginx -t echo ✅ Nginx 配置正确 || echo ❌ 配置有误请检查# 输出基本信息echo Nginx 版本$(nginx -v 21)echo 默认站点目录/usr/share/nginx/html坑alias lsrm这类恶作剧我们用command -v而非which因为which在某些系统上行为不一致。—## 常见坑和解决方案### 坑 1变量未加引号导致的空格分割问题错误写法bashfilemy document.txtcat $file # 会拆成 cat my document.txt正确写法bashcat $file### 坑 2set -e与grep组合时脚本意外退出bashset -egrep error /var/log/syslog # 如果没匹配到返回非 0脚本直接退出解决方案加上|| true或改用set e临时关闭bashgrep error /var/log/syslog || true### 坑 3Crontab 中执行脚本环境变量缺失bash# 错误脚本里用到 $PATH 但 crontab 的 PATH 很短* * * * * /opt/myscript.sh正确做法在脚本头部固定环境或者用绝对路径bash#!/bin/bashexport PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:$PATH—## 总结Shell 脚本是运维工程师的肌肉记忆。今天我带你过了一遍文件管理、系统监控、网络检测、备份、进程守护、配置部署等 10 个高频场景。它们虽然简单但每一行都是生产环境中踩坑换来的经验。学习建议1. 不要只是复制自己手打一遍改一个参数跑跑看。2. 逐渐养成好习惯变量加引号、错误处理、日志记录。3. 遇到重复 3 次以上的手动操作就考虑写成脚本。这些脚本你可以直接保存到一个~/scripts/目录配合 crontab 和别名每天帮你省下至少半小时。—## 推荐阅读- ShellCheck — 在线 Shell 脚本语法检查工具- Google Shell 风格指南- 《Linux Shell 脚本攻略》—— 最实操的 Shell 入门书—觉得有用点个收藏下次运维不慌张。