在现代 DevOps 实践中,Shell 脚本虽然“古老”,但依然是系统管理员和开发工程师不可或缺的利器。它轻量、高效、无需额外依赖,特别适合在 Linux 环境下完成自动化任务。本文将通过三个典型场景——自动化部署、日志分析和性能监控,带你用 Shell 脚本构建一套实用的运维工具链。
一、自动化部署脚本(Auto Deploy)
场景说明
每次发布新版本时,需要拉取代码、停止旧服务、部署新包、启动服务并验证状态。手动操作不仅繁琐,还容易出错。
脚本实现(deploy.sh)
#!/bin/bash # 配置区 APP_NAME="myapp" GIT_REPO="https://github.com/yourname/myapp.git" DEPLOY_DIR="/opt/$APP_NAME" LOG_FILE="/var/log/deploy_$(date +%Y%m%d).log" # 日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # 检查权限 if [ "$(id -u)" -ne 0 ]; then log "请以 root 或 sudo 运行此脚本!" exit 1 fi # 停止服务 log "正在停止 $APP_NAME 服务..." systemctl stop $APP_NAME || log "停止服务失败,继续部署..." # 备份旧版本 if [ -d "$DEPLOY_DIR" ]; then BACKUP_DIR="/opt/backup/${APP_NAME}_$(date +%Y%m%d_%H%M%S)" mkdir -p "$BACKUP_DIR" cp -r "$DEPLOY_DIR"/* "$BACKUP_DIR"/ log "旧版本已备份至 $BACKUP_DIR" fi # 拉取最新代码 rm -rf /tmp/${APP_NAME}_build git clone "$GIT_REPO" /tmp/${APP_NAME}_build if [ $? -ne 0 ]; then log "Git 克隆失败!" exit 1 fi # 部署新版本 mkdir -p "$DEPLOY_DIR" cp -r /tmp/${APP_NAME}_build/* "$DEPLOY_DIR"/ chown -R appuser:appgroup "$DEPLOY_DIR" # 启动服务 log "正在启动 $APP_NAME 服务..." systemctl start $APP_NAME # 验证服务状态 sleep 3 if systemctl is-active --quiet $APP_NAME; then log "✅ 部署成功!服务运行中。" else log "❌ 服务启动失败!请检查日志。" exit 1 fi使用建议:配合 Jenkins 或 GitLab CI 触发,实现一键发布。
二、日志分析脚本(Log Analyzer)
场景说明
Web 服务器每天产生大量访问日志,我们需要快速找出:
- 访问最多的 IP
- 返回 5xx 错误的请求
- 异常高频访问(可能为爬虫或攻击)
脚本实现(analyze_access_log.sh)
#!/bin/bash LOG_FILE=${1:-/var/log/nginx/access.log} OUTPUT_DIR="/tmp/log_analysis_$(date +%Y%m%d)" mkdir -p "$OUTPUT_DIR" echo "📊 正在分析日志: $LOG_FILE" # 1. Top 10 访问 IP awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10 > "$OUTPUT_DIR/top_ips.txt" # 2. 5xx 错误统计 awk '$9 ~ /^5[0-9][0-9]$/ {print $0}' "$LOG_FILE" | wc -l > "$OUTPUT_DIR/5xx_count.txt" awk '$9 ~ /^5[0-9][0-9]$/ {print $1, $7, $9}' "$LOG_FILE" | head -20 > "$OUTPUT_DIR/5xx_samples.txt" # 3. 每小时请求量趋势(假设日志格式含 [10/Dec/2025:14:23:01) awk -F'[][]' '{print substr($2,14,2)}' "$LOG_FILE" | sort | uniq -c > "$OUTPUT_DIR/hourly_requests.txt" # 4. 异常高频 IP(每分钟超过 100 次) awk '{ ip = $1 time = substr($4, 2, 16) # [10/Dec/2025:14:23 gsub(/:/, "-", time) key = ip "-" time count[key]++ } END { for (k in count) { if (count[k] > 100) print k, count[k] } }' "$LOG_FILE" > "$OUTPUT_DIR/suspicious_ips.txt" echo "✅ 分析完成!结果保存在 $OUTPUT_DIR" ls -lh "$OUTPUT_DIR"提示:可结合
cron每天凌晨自动运行,并邮件发送报告。
三、性能监控脚本(System Monitor)
场景说明
服务器资源异常可能导致服务中断。我们需要实时监控 CPU、内存、磁盘和负载,并在阈值超标时告警。
脚本实现(monitor.sh)
#!/bin/bash THRESHOLD_CPU=80 THRESHOLD_MEM=85 THRESHOLD_DISK=90 ALERT_EMAIL="admin@example.com" # 获取当前指标 CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print 100 - $8}') MEM_USAGE=$(free | awk 'NR==2{printf "%.0f", $3*100/$2}') DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%') LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | cut -d',' -f1) # 日志记录 echo "$(date): CPU=$CPU_USAGE%, MEM=$MEM_USAGE%, DISK=$DISK_USAGE%, LOAD=$LOAD_AVG" # 告警逻辑 ALERT_MSG="" if (( $(echo "$CPU_USAGE > $THRESHOLD_CPU" | bc -l) )); then ALERT_MSG+="⚠️ CPU 使用率过高: ${CPU_USAGE}%\n" fi if [ "$MEM_USAGE" -gt "$THRESHOLD_MEM" ]; then ALERT_MSG+="⚠️ 内存使用率过高: ${MEM_USAGE}%\n" fi if [ "$DISK_USAGE" -gt "$THRESHOLD_DISK" ]; then ALERT_MSG+="⚠️ 磁盘使用率过高: ${DISK_USAGE}%\n" fi if [ -n "$ALERT_MSG" ]; then echo -e "$ALERT_MSG" | mail -s "[告警] 服务器资源异常" "$ALERT_EMAIL" # 或使用 curl 发送企业微信/钉钉通知 fi