10 个实用的 Shell 脚本

—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/myapp"RETENTION_DAYS=7CLEANUP_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 -F'load 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_LIST="192.168.1.1192.168.1.10192.168.1.20google.com"TIMEOUT=3check_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_USER="backup_user"DB_PASS="your_password"DB_NAME="production_db"BACKUP_DIR="/data/backup/mysql"DATE_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 检测失败登录,动态封禁THRESHOLD=5BLOCK_TIME=3600 # 秒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/www"TARGET="backup@192.168.1.100:/backup/www"EXCLUDE_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/snapshot"mkdir -p "$BACKUP_BASE/$DATE_TAG"cp -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_NAME="java -jar myapp.jar"PID_FILE="/var/run/myapp.pid"START_CMD="/usr/local/myapp/start.sh"# 检查进程是否存在if ! pgrep -f "$PROCESS_NAME" > /dev/null 2>&1; then echo "$(date) 进程 ${PROCESS_NAME} 已挂,尝试重启..." >> /var/log/keepalive.log $START_CMD # 等待几秒检查是否启动成功 sleep 5 if pgrep -f "$PROCESS_NAME" > /dev/null 2>&1; 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/reports"HTML_FILE="${REPORT_DIR}/report_$(date +%Y%m%d).html"mkdir -p "$REPORT_DIR"# 采集数据HOSTNAME=$(hostname)UPTIME=$(uptime -p)DISK=$(df -h / | tail -1 | awk '{print $4" 可用(共"$2")"}')# 生成 HTMLcat > "$HTML_FILE" <<EOF<!DOCTYPE html><html><head><title>系统巡检 - $HOSTNAME</title></head><body><h1>巡检报告:$HOSTNAME</h1><p>生成时间:$(date '+%Y-%m-%d %H:%M')</p><h2>运行时长</h2><p>$UPTIME</p><h2>磁盘剩余</h2><p>$DISK</p><h2>内存使用</h2><pre>$(free -h)</pre></body></html>EOFecho "报告已生成:$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 2>&1)"echo "默认站点目录:/usr/share/nginx/html"alias ls="rm" 这类恶作剧?我们用 command -v 而非 which,因为 which 在某些系统上行为不一致。—## 常见坑和解决方案### 坑 1:变量未加引号导致的空格分割问题错误写法bashfile="my document.txt"cat $file # 会拆成 cat my document.txt正确写法bashcat "$file"### 坑 2:set -egrep 组合时脚本意外退出bashset -egrep "error" /var/log/syslog # 如果没匹配到,返回非 0,脚本直接退出!解决方案:加上 || true 或改用 set +e 临时关闭:bashgrep "error" /var/log/syslog || true### 坑 3:Crontab 中执行脚本环境变量缺失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 入门书觉得有用?点个收藏,下次运维不慌张。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值