1. Shell脚本在运维工作中的核心价值
作为一名拥有多年一线运维经验的工程师,我深刻体会到Shell脚本在日常工作中的重要性。它不仅是自动化运维的基石,更是提升工作效率的利器。通过编写高质量的Shell脚本,我们可以将重复性工作转化为自动化流程,减少人为错误,提高系统稳定性。
在运维领域,Shell脚本主要应用于以下几个核心场景:
- 系统监控:实时监控CPU、内存、磁盘、网络等关键指标
- 服务部署:实现一键安装、配置和启动各类服务
- 日志分析:快速提取和分析系统日志中的关键信息
- 数据备份:自动化执行数据库和文件系统的备份任务
- 安全管理:定期检查系统安全状态,防范潜在风险
2. 内存监控脚本深度解析
2.1 脚本功能与设计思路
内存监控是系统运维中最基础也最重要的任务之一。我们的目标是编写一个能够实时监控内存使用情况,并在内存使用率超过阈值时发出告警的脚本。
这个脚本的核心功能包括:
- 实时计算当前内存使用率
- 判断使用率是否超过预设阈值(80%)
- 根据判断结果输出相应的告警信息
- 记录告警日志以便后续分析
2.2 关键代码实现与优化
bash复制#!/bin/bash
# 获取当前时间戳,用于日志记录
ctime=$(date +%Y%m%d%H%M%S)
log="/var/log/$0.log"
# 确保日志目录存在
mkdir -p "$(dirname "$log")"
# 获取内存总量和剩余内存(单位:KB)
total=$(free | grep Mem | awk '{print $2}')
m_free=$(free | grep Mem | awk '{print $4}')
# 计算内存使用率(整数)
used_percent=$(( (total - m_free) * 100 / total ))
# 判断并输出告警信息
if (( used_percent >= 80 )); then
echo "警告!你的内存使用率超过80%,目前使用率是$used_percent%"
echo "[$ctime] 警告!你的内存使用率超过80%,目前使用率是$used_percent%" >> "$log"
else
echo "你的内存使用率是$used_percent%,还可以继续运行其他的程序,放心使用"
fi
优化建议:
- 添加日志轮转功能,防止日志文件过大
- 增加邮件或短信告警功能,实现多渠道通知
- 设置连续告警抑制,避免告警风暴
2.3 实际应用中的注意事项
在实际生产环境中使用内存监控脚本时,需要注意以下几点:
- 监控频率:不宜设置过高的监控频率,一般建议1-5分钟一次
- 阈值设置:根据实际业务需求调整告警阈值
- 日志管理:定期清理历史日志,避免占用过多磁盘空间
- 权限控制:确保脚本执行账户有足够的权限读取内存信息
3. Nginx一键部署脚本详解
3.1 编译安装 vs Yum安装
在Linux系统中,Nginx的安装主要有两种方式:
-
Yum安装:
- 优点:简单快捷,依赖自动解决
- 缺点:版本可能较旧,定制化选项有限
-
源码编译安装:
- 优点:版本可控,可深度定制
- 缺点:过程复杂,需要手动解决依赖
对于生产环境,我强烈推荐使用源码编译安装,因为它可以提供更好的性能和更高的灵活性。
3.2 完整的一键安装脚本
bash复制#!/bin/bash
# 安装依赖包
yum install gcc pcre2 pcre2-devel openssl openssl-devel zlib zlib-devel -y
# 创建专用用户
id xiaoyu || useradd xiaoyu
# 准备安装目录
mkdir -p /nginx
cd /nginx
curl -O https://nginx.org/download/nginx-1.28.2.tar.gz
# 解压源码包
tar xf nginx-1.28.2.tar.gz
cd nginx-1.28.2
# 配置编译选项
./configure --prefix=/usr/local/xiaoyu --user=xiaoyu --group=xiaoyu --with-http_ssl_module --with-http_v2_module --with-stream
if (( $? != 0 ));then
echo "编译配置失败,请检查错误信息"
exit 1
fi
# 编译并安装
make -j 2 && make install
# 设置环境变量
echo "PATH=/usr/local/xiaoyu/sbin/:$PATH" >>/etc/bashrc
source /etc/bashrc
# 配置systemd服务
cat > /usr/lib/systemd/system/nginx.service << EOF
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/xiaoyu/logs/nginx.pid
ExecStartPre=/usr/bin/rm -f /usr/local/xiaoyu/logs/nginx.pid
ExecStartPre=/usr/local/xiaoyu/sbin/nginx -t
ExecStart=/usr/local/xiaoyu/sbin/nginx
ExecReload=/usr/local/xiaoyu/sbin/nginx -s reload
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=mixed
PrivateTmp=true
User=xiaoyu
Group=xiaoyu
[Install]
WantedBy=multi-user.target
EOF
# 设置权限
chown -R xiaoyu:xiaoyu /usr/local/xiaoyu/
chmod -R 755 /usr/local/xiaoyu/
setcap 'cap_net_bind_service=+ep' /usr/local/xiaoyu/sbin/nginx
# 清理可能存在的旧进程
pkill -9 nginx &>/dev/null
sleep 1
# 启动服务
systemctl daemon-reload
systemctl start nginx
systemctl enable nginx
# 关闭防火墙和SELinux
systemctl stop firewalld
systemctl disable firewalld
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/selinux/config
setenforce 0
echo "Nginx 安装完成!访问地址:http://$(hostname -I | awk '{print $1}')"
3.3 关键配置解析
-
编译选项说明:
--prefix:指定安装目录--user/--group:设置运行用户--with-http_ssl_module:启用HTTPS支持--with-http_v2_module:支持HTTP/2协议--with-stream:启用TCP/UDP代理功能
-
systemd服务配置要点:
Type=forking:Nginx以守护进程方式运行PIDFile:指定PID文件位置ExecStartPre:启动前检查配置和清理旧PIDUser/Group:指定运行身份,提高安全性
-
安全加固措施:
- 使用专用用户运行Nginx
- 限制目录权限(755)
- 关闭不必要的系统服务(firewalld、SELinux)
3.4 常见问题排查
-
端口冲突:
bash复制
netstat -tulnp | grep :80如果80端口被占用,可以修改Nginx配置文件或停止占用端口的服务。
-
权限问题:
bash复制chown -R xiaoyu:xiaoyu /usr/local/xiaoyu/ -
配置语法错误:
bash复制
/usr/local/xiaoyu/sbin/nginx -t -
启动失败:
检查错误日志:bash复制tail -f /usr/local/xiaoyu/logs/error.log
4. Nginx一键卸载脚本
4.1 卸载脚本设计原则
一个完善的卸载脚本应该做到:
- 彻底停止服务进程
- 清理所有安装文件
- 恢复系统配置
- 可选清理依赖包
4.2 完整卸载脚本
bash复制#!/bin/bash
# 停止并禁用服务
systemctl stop nginx &>/dev/null
systemctl disable nginx &>/dev/null
systemctl daemon-reload
systemctl reset-failed nginx &>/dev/null
# 强制终止残留进程
pkill -9 nginx &>/dev/null
killall -9 nginx &>/dev/null
# 删除安装目录
NGINX_INSTALL_DIR="/usr/local/xiaoyu"
[ -d "$NGINX_INSTALL_DIR" ] && rm -rf "$NGINX_INSTALL_DIR"
# 删除源码目录
NGINX_SRC_DIR="/nginx"
[ -d "$NGINX_SRC_DIR" ] && rm -rf "$NGINX_SRC_DIR"
# 删除服务文件
NGINX_SERVICE_FILE="/usr/lib/systemd/system/nginx.service"
[ -f "$NGINX_SERVICE_FILE" ] && rm -f "$NGINX_SERVICE_FILE"
# 清理环境变量
sed -i '/PATH=\/usr\/local\/xiaoyu\/sbin\/:/d' /etc/bashrc
source /etc/bashrc
# 可选删除用户
read -p "是否删除 xiaoyu 用户?(y/n,默认 n):" DEL_USER
if [ "$DEL_USER" = "y" ] || [ "$DEL_USER" = "Y" ]; then
userdel -r xiaoyu &>/dev/null
groupdel xiaoyu &>/dev/null
fi
# 清理端口绑定权限
setcap -r /usr/local/xiaoyu/sbin/nginx &>/dev/null
echo "Nginx 已彻底卸载"
echo "如需清理依赖包,请执行:yum remove gcc pcre2 pcre2-devel openssl openssl-devel zlib zlib-devel -y"
4.3 卸载过程中的注意事项
- 数据备份:卸载前确保已备份Nginx配置文件和数据
- 服务依赖:检查是否有其他服务依赖当前Nginx实例
- 用户确认:删除用户前确认该用户未被其他服务使用
- 依赖包处理:谨慎移除依赖包,避免影响其他服务
5. 综合监控脚本开发
5.1 CPU与磁盘监控实现
bash复制#!/bin/bash
# 定义日志路径
log_path=/var/log/
logfile=cpu_disk.log
# 获取CPU使用率
cpu_idle=$(top -bn 1|awk '/^%Cpu/ {print $8}')
cpu_used=$(echo "100 - $cpu_idle"|bc)
# 检查CPU使用率
result=$(echo "$cpu_used > 70"|bc)
if (( $result == 1 ));then
echo "警告:CPU使用率超过70%,当前值:$cpu_used%"
echo "$(date +%Y%m%d%H%M%S) CPU警告:$cpu_used%" >> $log_path$logfile
fi
# 检查磁盘使用率
df -h | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{print $5 " " $6}' | while read output; do
used=$(echo $output | awk '{print $1}' | cut -d'%' -f1)
partition=$(echo $output | awk '{print $2}')
if [ $used -ge 80 ]; then
echo "警告:分区 $partition 使用率超过80%,当前值:$used%"
echo "$(date +%Y%m%d%H%M%S) 磁盘警告:$partition $used%" >> $log_path$logfile
fi
done
5.2 监控脚本的进阶优化
-
性能数据采集:
bash复制# 获取系统负载 load=$(uptime | awk -F'load average: ' '{print $2}' | cut -d, -f1) # 获取内存使用情况 mem_total=$(free -m | awk '/Mem:/ {print $2}') mem_used=$(free -m | awk '/Mem:/ {print $3}') mem_percent=$(( mem_used * 100 / mem_total )) -
告警阈值配置化:
bash复制# 读取配置文件 source /etc/monitor.conf # 配置文件示例 CPU_WARNING=70 DISK_WARNING=80 MEM_WARNING=80 -
告警方式多样化:
bash复制# 邮件告警 echo "告警内容" | mail -s "系统告警" admin@example.com # 企业微信机器人告警 curl -s "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"msgtype":"text","text":{"content":"告警内容"}}'
5.3 生产环境部署建议
-
定时任务配置:
bash复制# 每5分钟执行一次监控 */5 * * * * /path/to/monitor_script.sh -
日志轮转配置:
bash复制# /etc/logrotate.d/monitor /var/log/cpu_disk.log { daily rotate 7 compress missingok notifempty } -
性能优化:
- 减少不必要的命令调用
- 使用更高效的命令组合
- 适当延长监控间隔
6. Shell脚本编程最佳实践
6.1 代码规范与可读性
-
变量命名:
- 使用有意义的变量名
- 全局变量使用大写,局部变量使用小写
- 常量使用readonly声明
-
函数封装:
bash复制function check_cpu_usage() { local threshold=$1 # 函数实现 } -
注释规范:
- 文件头注释说明脚本用途
- 函数注释说明功能和参数
- 复杂逻辑添加行注释
6.2 错误处理与日志记录
-
错误退出:
bash复制command || { echo "命令执行失败"; exit 1; } -
调试模式:
bash复制set -x # 开启调试 # 脚本代码 set +x # 关闭调试 -
日志分级:
bash复制log() { local level=$1 local msg=$2 echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $msg" >> $log_file } log "INFO" "脚本启动" log "ERROR" "发生错误"
6.3 性能优化技巧
-
减少子进程创建:
- 使用内置命令替代外部命令
- 合并多个命令为一个管道
-
高效文本处理:
- 使用awk替代多个grep
- 使用sed进行批量替换
-
并行处理:
bash复制for i in {1..10}; do (command $i) & done wait
7. 运维脚本的安全考量
7.1 权限管理
-
最小权限原则:
- 使用普通用户运行脚本
- 通过sudo授权特定命令
-
敏感信息保护:
bash复制# 使用配置文件存储密码 source /etc/script.conf # 或者使用环境变量 export DB_PASSWORD="secret"
7.2 输入验证
-
参数检查:
bash复制if [ -z "$1" ]; then echo "Usage: $0 <parameter>" exit 1 fi -
防注入处理:
bash复制# 使用引号包裹变量 grep "$user_input" file.txt # 或者进行输入过滤 safe_input=$(echo "$user_input" | tr -cd '[:alnum:]_-')
7.3 审计与追踪
-
操作审计:
bash复制# 记录关键操作 echo "$(date) $(whoami) 执行了 $0 参数: $@" >> /var/log/operation.log -
版本控制:
- 使用Git管理脚本版本
- 添加变更日志
8. 运维脚本的扩展与集成
8.1 与配置管理工具集成
-
Ansible集成:
bash复制# 在Ansible playbook中调用脚本 - name: Execute monitoring script command: /path/to/monitor_script.sh register: script_output -
SaltStack集成:
bash复制# Salt state文件中调用脚本 run_monitor_script: cmd.run: - name: /path/to/monitor_script.sh - require: - file: /path/to/monitor_script.sh
8.2 与监控系统对接
-
Prometheus exporter:
bash复制# 输出Prometheus格式的指标 echo "# HELP cpu_usage CPU usage percentage" echo "# TYPE cpu_usage gauge" echo "cpu_usage $cpu_used" -
Zabbix监控项:
bash复制# 返回Zabbix可识别的值 zabbix_sender -z zabbix_server -k "cpu.usage" -o "$cpu_used"
8.3 自动化运维平台构建
-
Web界面集成:
- 提供脚本执行接口
- 展示执行结果
-
任务调度系统:
- 定时执行监控脚本
- 异常自动修复
-
告警中心:
- 统一告警入口
- 告警分级处理
通过将这些脚本集成到完整的运维体系中,可以构建出高效、可靠的自动化运维平台,大幅提升运维效率和质量。