您好,登录后才能下订单哦!
# 生产环境中有哪些常用的Shell脚本
## 引言
在现代IT基础设施管理中,Shell脚本作为自动化运维的核心工具,几乎渗透到生产环境的每个角落。根据2023年DevOps调查报告显示,78%的企业在生产环境中使用Shell脚本实现关键任务的自动化。本文将深入剖析生产环境中高频使用的Shell脚本类型,通过实际案例揭示其实现原理,并提供性能优化方案和安全实践建议。
## 一、系统监控类脚本
### 1.1 资源监控脚本
```bash
#!/bin/bash
# 资源监控告警脚本
THRESHOLD_CPU=80
THRESHOLD_MEM=85
THRESHOLD_DISK=90
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
MEM_USAGE=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
DISK_USAGE=$(df -h / | awk '{print $5}' | tail -1 | sed 's/%//')
[ $(echo "$CPU_USAGE > $THRESHOLD_CPU" | bc) -eq 1 ] && \
echo "CPU警报: ${CPU_USAGE}%" | mail -s "CPU告警" admin@example.com
[ $(echo "$MEM_USAGE > $THRESHOLD_MEM" | bc) -eq 1 ] && \
echo "内存警报: ${MEM_USAGE}%" | mail -s "内存告警" admin@example.com
[ $DISK_USAGE -gt $THRESHOLD_DISK ] && \
echo "磁盘警报: ${DISK_USAGE}%" | mail -s "磁盘告警" admin@example.com
关键改进:
- 使用bc
进行浮点数比较
- 多指标综合监控
- 邮件告警集成
#!/bin/bash
# 进程守护脚本
SERVICE="nginx"
PID=$(pgrep -x "$SERVICE")
if [ -z "$PID" ]; then
echo "$(date): $SERVICE 服务宕机,正在重启..." >> /var/log/service_monitor.log
systemctl start $SERVICE
# 二次验证
sleep 5
if ! pgrep -x "$SERVICE" >/dev/null; then
echo "$(date): 重启失败,发送告警" >> /var/log/service_monitor.log
mail -s "$SERVICE 服务异常" admin@example.com < /var/log/service_monitor.log
fi
fi
增强特性: - 重启失败二次验证 - 日志记录时间戳 - 状态变更历史追踪
#!/bin/bash
# 智能日志轮转脚本
LOG_DIR="/var/log/app"
MAX_SIZE="200M"
RETENTION_DAYS=30
find $LOG_DIR -name "*.log" -type f -size +$MAX_SIZE | while read LOGFILE
do
TIMESTAMP=$(date +%Y%m%d%H%M%S)
gzip -c $LOGFILE > "${LOGFILE}.${TIMESTAMP}.gz"
> $LOGFILE
done
# 过期日志清理
find $LOG_DIR -name "*.gz" -mtime +$RETENTION_DAYS -exec rm -f {} \;
优化点: - 按大小而非时间触发轮转 - 保留压缩副本而非直接删除 - 并行处理加速(GNU parallel)
#!/bin/bash
# 实时错误日志监控
ERROR_PATTERNS=("500 Internal Server Error" "OutOfMemory" "Connection refused")
tail -F /var/log/app/error.log | while read LINE
do
for PATTERN in "${ERROR_PATTERNS[@]}"; do
if echo "$LINE" | grep -q "$PATTERN"; then
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 检测到错误: $LINE" >> /var/log/error_monitor.log
# 频率限制:每分钟最多告警一次
[ ! -f /tmp/last_alert ] || find /tmp/last_alert -mmin +1 | grep -q . && \
echo "紧急错误: $PATTERN\n完整日志: $LINE" | mail -s "应用错误告警" admin@example.com && \
touch /tmp/last_alert
fi
done
done
高级特性: - 模式匹配数组 - 频率限制机制 - 上下文日志记录
#!/bin/bash
# MySQL全量+增量备份
BACKUP_DIR="/backup/mysql"
CONFIG_FILE="/etc/mysql/backup.cnf"
DATE=$(date +%Y%m%d)
FULL_BACKUP_DAY=0 # 周日全备
[ ! -d "$BACKUP_DIR" ] && mkdir -p "$BACKUP_DIR"
if [ $(date +%w) -eq $FULL_BACKUP_DAY ]; then
# 全量备份
FILENAME="full-$DATE.sql.gz"
mysqldump --defaults-file=$CONFIG_FILE --all-databases --single-transaction | gzip > $BACKUP_DIR/$FILENAME
else
# 增量备份
LAST_FULL=$(ls -t $BACKUP_DIR/full-* | head -1)
FILENAME="incr-$DATE.sql.gz"
mysqlbinlog --read-from-remote-server --raw --stop-never \
--result-file=$BACKUP_DIR/incr/ $LAST_FULL 2>/dev/null &
# 压缩前一天增量
find $BACKUP_DIR/incr/ -name "*.sql" -mtime +1 -exec gzip {} \;
fi
# 备份验证
if [ ! -s $BACKUP_DIR/$FILENAME ]; then
echo "备份失败: $FILENAME" | mail -s "MySQL备份异常" admin@example.com
fi
# 清理旧备份
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete
专业实践: - 全量+增量组合策略 - 备份文件完整性验证 - 自动清理机制
#!/bin/bash
# LVM快照备份
VOLUME_GROUP="vg_data"
LOGICAL_VOLUME="lv_app"
MOUNT_POINT="/app"
SNAPSHOT_SIZE="5G"
BACKUP_DIR="/backup/snapshots"
lvcreate -L$SNAPSHOT_SIZE -s -n ${LOGICAL_VOLUME}_snap /dev/$VOLUME_GROUP/$LOGICAL_VOLUME
mkdir -p $BACKUP_DIR/$(date +%Y%m%d)
mount /dev/$VOLUME_GROUP/${LOGICAL_VOLUME}_snap $MOUNT_POINT
rsync -aHAX --delete $MOUNT_POINT/ $BACKUP_DIR/$(date +%Y%m%d)/
umount $MOUNT_POINT
lvremove -f /dev/$VOLUME_GROUP/${LOGICAL_VOLUME}_snap
# 校验备份完整性
if [ $(find $BACKUP_DIR/$(date +%Y%m%d) -type f | wc -l) -eq 0 ]; then
echo "快照备份失败" | mail -s "LVM备份异常" admin@example.com
fi
关键技术: - LVM写时复制快照 - 原子性文件同步 - 资源自动释放
#!/bin/bash
# 零停机部署脚本
CURRENT_DEPLOY="/var/www/current"
NEW_DEPLOY="/var/www/releases/$(date +%Y%m%d%H%M%S)"
OLD_DEPLOY=""
[ -L "$CURRENT_DEPLOY" ] && OLD_DEPLOY=$(readlink "$CURRENT_DEPLOY")
# 准备新版本
rsync -az --exclude=".git" /build/ $NEW_DEPLOY/
cd $NEW_DEPLOY && npm install --production
# 测试验证
if ! curl -Isf "http://localhost:3000/health" >/dev/null; then
echo "新版本健康检查失败" >&2
rm -rf $NEW_DEPLOY
exit 1
fi
# 切换流量
ln -sfn $NEW_DEPLOY $CURRENT_DEPLOY
systemctl reload nginx
# 旧版本清理
[ -n "$OLD_DEPLOY" ] && nohup bash -c "sleep 3600 && rm -rf $OLD_DEPLOY" &
生产级特性: - 原子性切换 - 健康检查机制 - 延迟清理旧版本
#!/bin/bash
# 动态配置生成器
CONFIG_TEMPLATE="/templates/nginx.conf.tpl"
OUTPUT_FILE="/etc/nginx/conf.d/app.conf"
declare -A CONFIG_VARS=(
["WORKER_PROCESSES"]=$(nproc)
["KEEPALIVE_TIMEOUT"]=75
["CLIENT_MAX_BODY_SIZE"]="50M"
)
# 模板渲染
> $OUTPUT_FILE
while IFS= read -r LINE; do
for VAR in "${!CONFIG_VARS[@]}"; do
LINE=${LINE//\{\{$VAR\}\}/${CONFIG_VARS[$VAR]}}
done
echo "$LINE" >> $OUTPUT_FILE
done < $CONFIG_TEMPLATE
# 配置验证
if ! nginx -t; then
cp $OUTPUT_FILE ${OUTPUT_FILE}.error
echo "配置生成错误,已保存到 ${OUTPUT_FILE}.error" >&2
exit 1
fi
systemctl reload nginx
最佳实践: - 变量自动填充 - 配置语法预检 - 错误配置存档
#!/bin/bash
# 文件完整性校验
BASE_DIR="/etc"
HASH_FILE="/var/security/baseline_hashes.md5"
ALERT_EML="security@example.com"
[ ! -d "$(dirname $HASH_FILE)" ] && mkdir -p "$(dirname $HASH_FILE)"
# 基线建立模式
if [ "$1" == "--init" ]; then
find $BASE_DIR -type f -exec md5sum {} + > $HASH_FILE
chmod 600 $HASH_FILE
exit 0
fi
# 检测模式
TEMP_FILE=$(mktemp)
find $BASE_DIR -type f -exec md5sum {} + > $TEMP_FILE
diff <(sort $HASH_FILE) <(sort $TEMP_FILE) | grep '^[<>]' > /var/security/diff_report.txt
if [ -s /var/security/diff_report.txt ]; then
echo "发现文件变更:" | mail -a /var/security/diff_report.txt -s "文件完整性警报" $ALERT_EML
fi
rm $TEMP_FILE
安全机制: - 基线哈希校验 - 变更差异报告 - 敏感权限控制
#!/bin/bash
# 动态防火墙管理
WHITELIST=(192.168.1.0/24 10.0.0.5)
HIGH_RISK_PORTS=(135 139 445 3389)
# 清空现有规则
iptables -F
iptables -X
iptables -Z
# 默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 白名单处理
for IP in "${WHITELIST[@]}"; do
iptables -A INPUT -s $IP -j ACCEPT
done
# 基础服务放行
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 高危端口封锁
for PORT in "${HIGH_RISK_PORTS[@]}"; do
iptables -A INPUT -p tcp --dport $PORT -j DROP
iptables -A INPUT -p udp --dport $PORT -j DROP
done
# 应用规则持久化
iptables-save > /etc/iptables.rules
防御策略: - 默认拒绝原则 - 白名单机制 - 高危端口自动封锁
#!/bin/bash
# 高性能内核参数配置
SYSCTL_CONF="/etc/sysctl.d/99-tuning.conf"
cat > $SYSCTL_CONF <<EOF
# 网络栈优化
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
# 内存管理
vm.swappiness = 10
vm.dirty_ratio = 20
vm.dirty_background_ratio = 10
# 文件系统
fs.file-max = 2097152
fs.inotify.max_user_watches = 524288
EOF
sysctl -p $SYSCTL_CONF
调优重点: - TCP连接复用 - 内存换出策略 - 文件描述符限制
#!/bin/bash
# 磁盘调度策略优化
NVME_DEVICES=$(lsblk -d -o NAME,ROTA | grep '0$' | awk '{print $1}')
SSD_DEVICES=$(lsblk -d -o NAME,ROTA | grep '1$' | awk '{print $1}')
for DEV in $NVME_DEVICES; do
echo "none" > /sys/block/$DEV/queue/scheduler
echo "0" > /sys/block/$DEV/queue/nomerges
echo "1024" > /sys/block/$DEV/queue/nr_requests
done
for DEV in $SSD_DEVICES; do
echo "kyber" > /sys/block/$DEV/queue/scheduler
echo "2" > /sys/block/$DEV/queue/nomerges
echo "128" > /sys/block/$DEV/queue/nr_requests
done
优化策略: - NVMe设备无调度模式 - SSD自适应调度 - 请求队列深度调整
#!/bin/bash
# 跨平台环境检测
OS_NAME=$(uname -s)
ARCH=$(uname -m)
case $OS_NAME in
Linux)
# 识别Linux发行版
if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO=$ID
elif type lsb_release >/dev/null 2>&1; then
DISTRO=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
else
DISTRO=$(uname -o | tr '[:upper:]' '[:lower:]')
fi
;;
Darwin)
DISTRO="macos"
;;
*)
DISTRO="unknown"
;;
esac
# 架构适配
case $ARCH in
x86_64)
BINARY_ARCH="amd64"
;;
arm*)
BINARY_ARCH="arm"
;;
aarch64)
BINARY_ARCH="arm64"
;;
*)
BINARY_ARCH=$ARCH
;;
esac
echo "检测到系统: $DISTRO $BINARY_ARCH"
兼容性处理: - 发行版自动识别 - 架构类型映射 - 环境变量标准化
#!/bin/bash
# 符合ShellCheck标准的脚本模板
set -o errexit # 立即退出遇到错误
set -o nounset # 使用未定义变量时报错
set -o pipefail # 管道命令失败时整个命令失败
readonly SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
readonly LOG_FILE="/var/log/$(basename "$0").log"
function log() {
local level=$1
shift
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $@" | tee -a "$LOG_FILE"
}
function validate_params() {
if [ $# -lt 2 ]; then
log ERROR "参数不足,需要至少2个参数"
exit 1
fi
}
function main() {
validate_params "$@"
log INFO "脚本启动,参数: $*"
# 业务逻辑
local input_file=$1
local output_dir=$2
if [ ! -f "$input_file" ]; then
log ERROR "输入文件不存在: $input_file"
exit 2
fi
mkdir -p "$output_dir"
log INFO "处理完成"
}
main "$@"
工程化规范: - 严格错误处理 - 日志标准化 - 参数验证 - 函数模块化
”`bash #!/bin/bash
set -eo pipefail
array=(1 2 3) for i in “\({array[@]}"; do process "\)i”
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。