版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Shell脚本编程模板——运维/部署/日志处理分场景
标签:Shell、Bash、运维自动化、部署脚本、日志处理、awk、sed、grep、systemd、crontab
日期:2026年9月19日
一句话简介
从服务器巡检到蓝绿部署,从日志切割到错误聚合,完整覆盖运维、部署、日志处理三大场景的40+可直接运行的
Shell脚本模板,每个模板配场景说明、完整代码、参数解释、运行示例与排错指南。
适用人群
运维工程师、DevOps工程师,需要编写自动化运维脚本。
后端开发工程师,需要编写部署、发布、回滚脚本。
系统管理员,需要处理日志分析、监控告警任务。
已掌握Linux基础命令,希望系统学习Shell脚本编程的开发者。
文档类型
合集资料类。
关键词
Shell、Bash、运维、部署、日志处理、awk、sed、grep、systemd、crontab、数组、函数、trap、set-euo
pipefail、ShellCheck、蓝绿部署、日志切割、错误聚合、性能分析、并发控制、锁文件、信号处理。
目录
1.第一章工具与材料清单
2.第二章Shell编程核心基础
3.第三章运维场景脚本模板(14个)
4.第四章部署场景脚本模板(12个)
5.第五章日志处理场景脚本模板(12个)
6.第六章综合实战:全链路部署与监控
7.第七章避坑指南
8.第八章常见问题解答
9.第九章附录:速查表与工具
第一章工具与材料清单
工具/材料作用最低版本检查命令
BashShell解释器4.0+(推荐5.0+)bash--version
工具/材料作用最低版本检查命令
ShellCheck静态检查工具最新版shellcheck--version
awk文本处理GNUawk4.0+awk--version
sed流编辑器GNUsed4.0+sed--version
grep文本搜索GNUgrep3.0+grep--version
curlHTTP客户端7.0+curl--version
jqJSON处理1.6+jq--version
systemd服务管理最新版systemctl--version
rsync文件同步3.0+rsync--version
crontab定时任务系统内置crontab-l
1.1环境准备:零基础操作引导
做什么:验证Bash版本和常用工具。
怎么做:打开终端,输入以下命令,每输入一行按一次回车。
bash--version
awk--version|head-1
sed--version|head-1
grep--version|head-1
结果长什么样:终端显示各工具版本号。若bash--version低于4.0,部分脚本的关联数组和mapfile功能将不可
用。
1.2推荐目录结构
shell-automation/
├──lib/
│
├──common.sh
│
├──log.sh
│
└──utils.sh
├──ops/
│
├──server_check.sh
│
├──disk_monitor.sh
│
├──process_guard.sh
│
└──backup.sh
├──deploy/
│
├──deploy.sh
│
├──rollback.sh
│
├──blue_green.sh
│
└──health_check.sh
├──logs/
│
├──rotate.sh
│
├──analyze.sh
│
├──alert.sh
│
└──aggregate.sh
├──config/
│
└──config.env
└──README.md
1.3脚本模板开头规范
每个生产级Shell脚本开头必须包含以下内容:
#!/usr/bin/envbash
#脚本名称:deploy.sh
#功能描述:应用部署脚本
#作者:张开发
#创建日期:2026-09-19
#版本:1.0.0
#使用方法:./deploy.sh-eproduction-v1.2.3
set-euopipefail
IFS=$'\n\t'
关键说明:
set-e:命令失败立即退出。
set-u:使用未定义变量报错。
set-opipefail:管道中任一命令失败则整体失败。
IFS=$'\n\t':设置内部字段分隔符为换行和制表符,避免空格分词问题。
第二章Shell编程核心基础
2.1变量与参数
#变量赋值(等号两侧无空格)
APP_NAME="myapp"
VERSION="1.2.3"
#只读变量
readonlyAPP_NAME
#命令替换
CURRENT_DATE=$(date+%Y-%m-%d)
FILE_COUNT=$(ls-1|wc-l)
#算术运算
COUNT=$((COUNT+1))
TOTAL=$((10*5))
#默认值
PORT=${PORT:-8080}
#未设置时用8080
NAME=${NAME:="默认名称"}
#未设置时赋值默认值
#字符串长度
LEN=${#APP_NAME}
#字符串截取
PREFIX=${VERSION:0:1}
#第一个字符
SUFFIX=${VERSION:2}
#从第3个字符到末尾
#字符串替换
NEW=${VERSION//./-}
#所有点替换为横线
2.2位置参数与参数解析
#位置参数
#$0脚本名,$1第一个参数,$#参数个数,$@所有参数,$*所有参数(合并)
#getopts解析
whilegetopts"e:v:h"opt;do
case$optin
e)ENV="$OPTARG";;
v)VERSION="$OPTARG";;
h)usage;exit0;;
*)usage;exit1;;
esac
done
#手动解析长选项
while[[$#-gt0]];do
case$1in
--env)ENV="$2";shift2;;
--version)VERSION="$2";shift2;;
--help)usage;exit0;;
*)echo"未知参数:$1";exit1;;
esac
done
2.3条件判断
#字符串判断
if[["$ENV"=="production"]];then
echo"生产环境"
fi
#数值判断
if((COUNT>100));then
echo"超过100"
fi
#文件判断
if[[-f"$FILE"]];thenecho"文件存在";fi
if[[-d"$DIR"]];thenecho"目录存在";fi
if[[-r"$FILE"]];thenecho"可读";fi
if[[-w"$FILE"]];thenecho"可写";fi
if[[-x"$FILE"]];thenecho"可执行";fi
if[[-s"$FILE"]];thenecho"非空文件";fi
#逻辑组合
if[[-f"$FILE"&&-r"$FILE"]];then
echo"文件存在且可读"
fi
2.4数组与关联数组
#索引数组
SERVERS=("web1""web2""web3")
SERVERS+=("web4")
#追加
echo"${SERVERS[0]}"
#第一个
echo"${SERVERS[@]}"
#所有元素
echo"${#SERVERS[@]}"
#数组长度
#遍历
forserverin"${SERVERS[@]}";do
echo"处理:$server"
done
#关联数组(Bash4.0+)
declare-ACONFIG
CONFIG[host]="localhost"
CONFIG[port]="8080"
echo"${CONFIG[host]}"
#遍历关联数组
forkeyin"${!CONFIG[@]}";do
echo"$key=${CONFIG[$key]}"
done
2.5函数
#函数定义
log_info(){
localmessage="$1"
echo"[$(date+'%Y-%m-%d%H:%M:%S')][INFO]$message"
}
log_error(){
localmessage="$1"
echo"[$(date+'%Y-%m-%d%H:%M:%S')][ERROR]$message">&2
}
#带返回值
check_file(){
localfile="$1"
if[[-f"$file"]];then
return0
else
return1
fi
}
#返回字符串(通过echo)
get_timestamp(){
echo"$(date+%Y%m%d_%H%M%S)"
}
TIMESTAMP=$(get_timestamp)
2.6trap信号处理
#清理函数
cleanup(){
localexit_code=$?
echo"执行清理..."
rm-f"$TEMP_FILE"
exit$exit_code
}
#注册信号处理
trapcleanupEXITINTTERM
#EXIT:脚本退出时执行
#INT:Ctrl+C
#TERM:kill命令
#ERR:命令失败(需配合set-e)
2.7并发控制
#后台执行+wait
forserverin"${SERVERS[@]}";do
process_server"$server"&
done
#等待所有后台任务
wait
#限制并发数
MAX_JOBS=5
current_jobs=0
forserverin"${SERVERS[@]}";do
while((current_jobs>=MAX_JOBS));do
wait-n
#等待任一任务完成
((current_jobs--))
done
process_server"$server"&
((current_jobs++))
done
wait
第三章运维场景脚本模板(14个)
脚本1:服务器基础巡检
场景:每日巡检服务器CPU、内存、磁盘、负载、网络状态,输出报告。
#!/usr/bin/envbash
#脚本名称:server_check.sh
#功能描述:服务器基础巡检
#使用方法:./server_check.sh
set-euopipefail
IFS=$'\n\t'
readonlyREPORT_DIR="/var/log/server_check"
readonlyTIMESTAMP=$(date+%Y%m%d_%H%M%S)
readonlyREPORT_FILE="${REPORT_DIR}/check_${TIMESTAMP}.log"
mkdir-p"$REPORT_DIR"
log(){
echo"[$(date+'%Y-%m-%d%H:%M:%S')]$*"|tee-a"$REPORT_FILE"
}
check_cpu(){
localload
load=$(uptime|awk-F'loadaverage:''{print$2}'|xargs)
localcores
cores=$(nproc)
log"CPU核心数:$cores"
log"系统负载:$load"
}
check_memory(){
localtotalusedfreepercent
total=$(free-m|awk'/^Mem:/{print$2}')
used=$(free-m|awk'/^Mem:/{print$3}')
free=$(free-m|awk'/^Mem:/{print$4}')
percent=$((used*100/total))
log"内存:总${total}MB已用${used}MB空闲${free}MB使用率${percent}%"
if((percent>90));then
log"[警告]内存使用率超过90%"
fi
}
check_disk(){
log"磁盘使用情况:"
df-h|grep-vE'^Filesystem|tmpfs|cdrom'|whileread-rline;do
localusage
usage=$(echo"$line"|awk'{print$5}'|sed's/%//')
localmount
mount=$(echo"$line"|awk'{print$6}')
log"
$line"
if((usage>85));then
log"[警告]挂载点$mount使用率${usage}%"
fi
done
}
check_network(){
log"网络连接数:"
localestablished
established=$(ss-tan|grep-cESTAB||echo0)
log"ESTABLISHED:$established"
}
check_services(){
localservices=("sshd""cron")
forsvcin"${services[@]}";do
ifsystemctlis-active--quiet"$svc"2>/dev/null;then
log"服务$svc:运行中"
else
log"[警告]服务$svc:未运行"
fi
done
}
main(){
log"=====服务器巡检开始====="
log"主机名:$(hostname)"
log"IP地址:$(hostname-I|awk'{print$1}')"
check_cpu
check_memory
check_disk
check_network
check_services
log"=====巡检完成,报告:$REPORT_FILE====="
}
main"$@"
运行示例:
chmod+xserver_check.sh
./server_check.sh
报错了怎么办:
systemctl:commandnotfound:非systemd系统,改用service命令或ps检查。
ss:commandnotfound:安装iproute2包,或改用netstat。
脚本2:磁盘空间监控与告警
#!/usr/bin/envbash
#脚本名称:disk_monitor.sh
#功能描述:磁盘空间监控,超过阈值告警
set-euopipefail
readonlyTHRESHOLD="${THRESHOLD:-85}"
readonlyALERT_LOG="/var/log/disk_alert.log"
check_disk_usage(){
localalert_count=0
whileread-rfilesystemsizeusedavailpercentmount;do
localusage
usage=${percent%\%}
if((usage>=THRESHOLD));then
localmsg="[$(date+'%Y-%m-%d%H:%M:%S')]磁盘告警:$mount使用率${usage}%(阈值
${THRESHOLD}%)"
echo"$msg"|tee-a"$ALERT_LOG"
((alert_count++))
fi
done<<(df-h|grep-vE'^Filesystem|tmpfs|cdrom|overlay')
if((alert_count>0));then
return1
fi
return0
}
check_inode_usage(){
whileread-rfilesysteminodesiusedifreepercentmount;do
localusage
usage=${percent%\%}
if((usage>=THRESHOLD));then
echo"[$(date+'%Y-%m-%d%H:%M:%S')]Inode告警:$mount使用率${usage}%"|tee-a
"$ALERT_LOG"
fi
done<<(df-i|grep-vE'^Filesystem|tmpfs|cdrom|overlay')
}
main(){
echo"开始磁盘监控,阈值:${THRESHOLD}%"
check_disk_usage
check_inode_usage
echo"监控完成"
}
main"$@"
脚本3:进程守护与自动重启
#!/usr/bin/envbash
#脚本名称:process_guard.sh
#功能描述:监控进程,异常退出自动重启
#使用方法:./process_guard.sh-p"nginx"-c"systemctlstartnginx"
set-euopipefail
PROCESS_NAME=""
RESTART_CMD=""
CHECK_INTERVAL=30
LOG_FILE="/var/log/process_guard.log"
usage(){
echo"用法:$0-p<进程名>-c<重启命令>[-i<检查间隔秒>]"
exit1
}
whilegetopts"p:c:i:h"opt;do
case$optin
p)PROCESS_NAME="$OPTARG";;
c)RESTART_CMD="$OPTARG";;
i)CHECK_INTERVAL="$OPTARG";;
h)usage;;
*)usage;;
esac
done
[[-z"$PROCESS_NAME"]]&&usage
[[-z"$RESTART_CMD"]]&&usage
log(){
echo"[$(date+'%Y-%m-%d%H:%M:%S')]$*"|tee-a"$LOG_FILE"
}
is_running(){
pgrep-f"$PROCESS_NAME">/dev/null2>&1
}
restart_process(){
log"进程$PROCESS_NAME未运行,执行重启..."
ifeval"$RESTART_CMD";then
log"重启成功"
else
log"[错误]重启失败"
fi
}
main(){
log"开始监控进程:$PROCESS_NAME,间隔:${CHECK_INTERVAL}秒"
whiletrue;do
if!is_running;then
restart_process
fi
sleep"$CHECK_INTERVAL"
done
}
main"$@"
脚本4:文件备份与清理
#!/usr/bin/envbash
#脚本名称:backup.sh
#功能描述:目录备份,压缩,自动清理旧备份
set-euopipefail
readonlySOURCE_DIR="${1:-/data/app}"
readonlyBACKUP_DIR="${2:-/backup}"
readonlyKEEP_DAYS="${3:-7}"
readonlyTIMESTAMP=$(date+%Y%m%d_%H%M%S)
readonlyBACKUP_NAME="backup_${TIMESTAMP}.tar.gz"
log(){
echo"[$(date+'%Y-%m-%d%H:%M:%S')]$*"
}
check_source(){
if[[!-d"$SOURCE_DIR"]];then
log"[错误]源目录不存在:$SOURCE_DIR"
exit1
fi
}
do_backup(){
mkdir-p"$BACKUP_DIR"
log"开始备份$SOURCE_DIR→$BACKUP_DIR/$BACKUP_NAME"
iftar-czf"$BACKUP_DIR/$BACKUP_NAME"-C"$(dirname"$SOURCE_DIR")""$(basename
"$SOURCE_DIR")";then
log"备份成功:$BACKUP_DIR/$BACKUP_NAME"
log"文件大小:$(du-h"$BACKUP_DIR/$BACKUP_NAME"|cut-f1)"
else
log"[错误]备份失败"
exit1
fi
}
cleanup_old(){
log"清理${KEEP_DAYS}天前的备份..."
localcount
count=$(find"$BACKUP_DIR"-name"backup_*.tar.gz"-mtime+"$KEEP_DAYS"|wc-l)
find"$BACKUP_DIR"-name"backup_*.tar.gz"-mtime+"$KEEP_DAYS"-delete
log"已清理$count个旧备份"
}
main(){
check_source
do_backup
cleanup_old
}
main"$@"
脚本5:系统资源使用率TopN
#!/usr/bin/envbash
#脚本名称:top_processes.sh
#功能描述:查看CPU/内存占用TopN进程
set-euopipefail
readonlyTOP_N="${1:-10}"
echo"=====CPU占用Top$TOP_N====="
psaux--sort=-%cpu|head-n$((TOP_N+1))|awk'{printf"%-10s%-8s%-6s%-6s%s\n",$1,
$2,$3,$4,$11}'
echo""
echo"=====内存占用Top$TOP_N====="
psaux--sort=-%mem|head-n$((TOP_N+1))|awk'{printf"%-10s%-8s%-6s%-6s%s\n",$1,
$2,$3,$4,$11}'
echo""
echo"=====磁盘IOTop$TOP_N====="
ifcommand-viotop>/dev/null2>&1;then
iotop-b-n1-o|head-n$((TOP_N+1))
else
echo"iotop未安装,跳过"
fi
脚本6:端口占用检查
#!/usr/bin/envbash
#脚本名称:check_ports.sh
#功能描述:批量检查端口监听状态
set-euopipefail
readonlyPORTS=(22804433306637980809090)
check_port(){
localport="$1"
ifss-tlnp2>/dev/null|grep-q":${port}";then
localprocess
process=$(ss-tlnp2>/dev/null|grep":${port}"|awk'{print$NF}'|head-1)
echo"端口$port:[监听中]$process"
else
echo"端口$port:[未监听]"
fi
}
main(){
echo"=====端口检查====="
forportin"${PORTS[@]}";do
check_port"$port"
done
}
main"$@"
脚本7:批量SSH远程执行
#!/usr/bin/envbash
#脚本名称:batch_ssh.sh
#功能描述:批量在多台服务器执行命令
set-euopipefail
readonlyHOSTS_FILE="${1:-hosts.txt}"
readonlyCOMMAND="${2:-uptime}"
readonlySSH_USER="${SSH_USER:-root}"
readonlySSH_PORT="${SSH_PORT:-22}"
readonlyMAX_PARALLEL=5
execute_remote(){
localhost="$1"
localoutput
ifoutput=$(ssh-p"$SSH_PORT"-oConnectTimeout=10-oStrictHostKeyChecking=no\
"${SSH_USER}@${host}""$COMMAND"2>&1);then
echo"[$host]成功:"
echo"$output"
else
echo"[$host]失败:$output"
fi
}
main(){
if[[!-f"$HOSTS_FILE"]];then
echo"主机文件不存在:$HOSTS_FILE"
exit1
fi
localcount=0
whileIFS=read-rhost;do
[[-z"$host"||"$host"=~^#]]&&continue
execute_remote"$host"&
((count++))
if((count%MAX_PARALLEL==0));then
wait
fi
done<"$HOSTS_FILE"
wait
}
main"$@"
脚本8:配置文件批量修改
#!/usr/bin/envbash
#脚本名称:config_update.sh
#功能描述:批量修改配置文件中的键值对
set-euopipefail
readonlyCONFIG_FILE="${1:-/etc/app/config.conf}"
readonlyKEY="${2:-}"
readonlyVALUE="${3:-}"
readonlyBACKUP_SUFFIX=".bak.$(date+%Y%m%d_%H%M%S)"
if[[-z"$KEY"||-z"$VALUE"]];then
echo"用法:$0<配置文件><键><值>"
exit1
fi
update_config(){
cp"$CONFIG_FILE""${CONFIG_FILE}${BACKUP_SUFFIX}"
echo"已备份:${CONFIG_FILE}${BACKUP_SUFFIX}"
ifgrep-q"^${KEY}=""$CONFIG_FILE";then
sed-i"s|^${KEY}=.*|${KEY}=${VALUE}|""$CONFIG_FILE"
echo"已更新:${KEY}=${VALUE}"
else
echo"${KEY}=${VALUE}">>"$CONFIG_FILE"
echo"已添加:${KEY}=${VALUE}"
fi
}
update_config
脚本9:Nginx日志切割
#!/usr/bin/envbash
#脚本名称:nginx_log_rotate.sh
#功能描述:Nginx日志按天切割,保留30天
set-euopipefail
readonlyLOG_DIR="/var/log/nginx"
readonlyKEEP_DAYS=30
readonlyYESTERDAY=$(date-d"yesterday"+%Y%m%d)
rotate_log(){
locallog_file="$1"
if[[!-f"$log_file"]];then
return
fi
localrotated="${log_file}.${YESTERDAY}"
mv"$log_file""$rotated"
gzip"$rotated"
echo"已切割:$log_file→${rotated}.gz"
}
reload_nginx(){
ifnginx-t2>/dev/null;then
nginx-sreopen2>/dev/null||systemctlreloadnginx
echo"Nginx已重新打开日志文件"
fi
}
cleanup_old(){
find"$LOG_DIR"-name"*.gz"-mtime+"$KEEP_DAYS"-delete
echo"已清理${KEEP_DAYS}天前的日志"
}
main(){
rotate_log"$LOG_DIR/access.log"
rotate_log"$LOG_DIR/error.log"
reload_nginx
cleanup_old
}
main"$@"
脚本10:服务健康检查
#!/usr/bin/envbash
#脚本名称:health_check.sh
#功能描述:HTTP服务健康检查,失败自动告警
set-euopipefail
readonlyURL="${1:-http://localhost:8080/health}"
readonlyTIMEOUT=10
readonlyRETRY=3
readonlyALERT_LOG="/var/log/health_alert.log"
check_health(){
localattempt=1
while((attempt<=RETRY));do
localhttp_code
http_code=$(curl-s-o/dev/null-w"%{http_code}"--max-time"$TIMEOUT""$URL"
2>/dev/null||echo"000")
if[["$http_code"=="200"]];then
echo"[$(date+'%Y-%m-%d%H:%M:%S')]健康检查通过:$URL(HTTP$http_code)"
return0
fi
echo"[$(date+'%Y-%m-%d%H:%M:%S')]第${attempt}次检查失败:HTTP$http_code"
((attempt++))
sleep2
done
echo"[$(date+'%Y-%m-%d%H:%M:%S')][告警]健康检查失败:$URL"|tee-a"$ALERT_LOG"
return1
}
check_health
脚本11:定时任务管理
#!/usr/bin/envbash
#脚本名称:cron_manager.sh
#功能描述:管理crontab任务,添加/删除/列出
set-euopipefail
ACTION="${1:-list}"
CRON_EXPR="${2:-}"
CRON_CMD="${3:-}"
case"$ACTION"in
list)
echo"=====当前定时任务====="
crontab-l2>/dev/null||echo"无定时任务"
;;
add)
if[[-z"$CRON_EXPR"||-z"$CRON_CMD"]];then
echo"用法:$0add'<cron表达式>''<命令>'"
exit1
fi
(crontab-l2>/dev/null;echo"$CRON_EXPR$CRON_CMD")|crontab-
echo"已添加:$CRON_EXPR$CRON_CMD"
;;
remove)
if[[-z"$CRON_CMD"]];then
echo"用法:$0remove'''<命令>'"
exit1
fi
crontab-l2>/dev/null|grep-v"$CRON_CMD"|crontab-
echo"已删除包含'$CRON_CMD'的任务"
;;
*)
echo"用法:$0{list|add|remove}"
exit1
;;
esac
脚本12:系统信息采集
#!/usr/bin/envbash
#脚本名称:system_info.sh
#功能描述:采集系统信息,输出JSON格式
set-euopipefail
get_os_info(){
localos_nameos_version
if[[-f/etc/os-release]];then
os_name=$(grep'^NAME='/etc/os-release|cut-d'"'-f2)
os_version=$(grep'^VERSION_ID='/etc/os-release|cut-d'"'-f2)
fi
echo"${os_name:-unknown}${os_version:-unknown}"
}
get_cpu_info(){
localmodelcores
model=$(grep'modelname'/proc/cpuinfo|head-1|cut-d':'-f2|xargs)
cores=$(nproc)
echo"${model}(${cores}核)"
}
get_memory_info(){
free-m|awk'/^Mem:/{printf"总%dMB已用%dMB使用率%d%%",$2,$3,$3*100/$2}'
}
get_disk_info(){
df-h/|awk'NR==2{printf"总%s已用%s使用率%s",$2,$3,$5}'
}
main(){
localhostnameipuptime_info
hostname=$(hostname)
ip=$(hostname-I|awk'{print$1}')
uptime_info=$(uptime-p2>/dev/null||uptime)
cat<<EOF
{
"hostname":"$hostname",
"ip":"$ip",
"os":"$(get_os_info)",
"cpu":"$(get_cpu_info)",
"memory":"$(get_memory_info)",
"disk":"$(get_disk_info)",
"uptime":"$uptime_info",
"timestamp":"$(date-Iseconds)"
}
EOF
}
main"$@"
脚本13:防火墙规则管理
#!/usr/bin/envbash
#脚本名称:firewall_manager.sh
#功能描述:管理firewalld规则
set-euopipefail
ACTION="${1:-list}"
PORT="${2:-}"
PROTOCOL="${3:-tcp}"
if!command-vfirewall-cmd>/dev/null2>&1;then
echo"firewalld未安装"
exit1
fi
case"$ACTION"in
list)
echo"=====已开放端口====="
firewall-cmd--list-ports
echo"=====已开放服务====="
firewall-cmd--list-services
;;
add)
if[[-z"$PORT"]];then
echo"用法:$0add<端口>[协议]"
exit1
fi
firewall-cmd--permanent--add-port="${PORT}/${PROTOCOL}"
firewall-cmd--reload
echo"已开放:${PORT}/${PROTOCOL}"
;;
remove)
if[[-z"$PORT"]];then
echo"用法:$0remove<端口>[协议]"
exit1
fi
firewall-cmd--permanent--remove-port="${PORT}/${PROTOCOL}"
firewall-cmd--reload
echo"已关闭:${PORT}/${PROTOCOL}"
;;
*)
echo"用法:$0{list|add|remove}"
exit1
;;
esac
脚本14:日志关键词告警
#!/usr/bin/envbash
#脚本名称:log_keyword_alert.sh
#功能描述:监控日志文件关键词,匹配时告警
set-euopipefail
readonlyLOG_FILE="${1:-/var/log/app/error.log}"
readonlyKEYWORDS="${2:-ERROR|FATAL|Exception}"
readonlyINTERVAL="${3:-60}"
readonlyALERT_LOG="/var/log/keyword_alert.log"
readonlySTATE_FILE="/tmp/log_keyword_alert.state"
if[[!-f"$LOG_FILE"]];then
echo"日志文件不存在:$LOG_FILE"
exit1
fi
LAST_POS=0
if[[-f"$STATE_FILE"]];then
LAST_POS=$(cat"$STATE_FILE")
fi
CURRENT_SIZE=$(stat-c%s"$LOG_FILE")
if((CURRENT_SIZE<LAST_POS));then
LAST_POS=0
fi
if((CURRENT_SIZE>LAST_POS));then
NEW_CONTENT=$(tail-c+$((LAST_POS+1))"$LOG_FILE")
MATCHES=$(echo"$NEW_CONTENT"|grep-E"$KEYWORDS"||true)
if[[-n"$MATCHES"]];then
echo"[$(date+'%Y-%m-%d%H:%M:%S')]匹配到关键词:"|tee-a"$ALERT_LOG"
echo"$MATCHES"|tee-a"$ALERT_LOG"
fi
echo"$CURRENT_SIZE">"$STATE_FILE"
fi
配合crontab使用:
*****/opt/scripts/log_keyword_alert.sh/var/log/app/error.log"ERROR|FATAL"
第四章部署场景脚本模板(12个)
脚本15:通用应用部署脚本
#!/usr/bin/envbash
#脚本名称:deploy.sh
#功能描述:应用部署脚本,支持版本切换
set-euopipefail
IFS=$'\n\t'
readonlyAPP_NAME="myapp"
readonlyDEPLOY_DIR="/opt/${APP_NAME}"
readonlyRELEASE_DIR="${DEPLOY_DIR}/releases"
readonlyCURRENT_LINK="${DEPLOY_DIR}/current"
readonlyBACKUP_DIR="${DEPLOY_DIR}/backups"
readonlyKEEP_RELEASES=5
readonlyTIMESTAMP=$(date+%Y%m%d_%H%M%S)
ENV=""
VERSION=""
PACKAGE=""
usage(){
cat<<EOF
用法:$0-e<环境>-v<版本>-p<包路径>
选项:
-e环境:production/staging/development
-v版本号
-p部署包路径
-h显示帮助
EOF
exit1
}
whilegetopts"e:v:p:h"opt;do
case$optin
e)ENV="$OPTARG";;
v)VERSION="$OPTARG";;
p)PACKAGE="$OPTARG";;
h)usage;;
*)usage;;
esac
done
[[-z"$ENV"||-z"$VERSION"||-z"$PACKAGE"]]&&usage
[[!-f"$PACKAGE"]]&&{echo"部署包不存在:$PACKAGE";exit1;}
log(){
echo"[$(date+'%Y-%m-%d%H:%M:%S')][$ENV]$*"
}
prepare_dirs(){
mkdir-p"$RELEASE_DIR""$BACKUP_DIR"
}
backup_current(){
if[[-L"$CURRENT_LINK"]];then
localcurrent_release
current_release=$(readlink-f"$CURRENT_LINK")
localbackup_name="backup_${TIMESTAMP}.tar.gz"
log"备份当前版本:$current_release"
tar-czf"${BACKUP_DIR}/${backup_name}"-C"$(dirname"$current_release")"
"$(basename"$current_release")"
log"备份完成:${BACKUP_DIR}/${backup_name}"
fi
}
deploy_new_version(){
localrelease_path="${RELEASE_DIR}/${VERSION}_${TIMESTAMP}"
mkdir-p"$release_path"
log"解压部署包到:$release_path"
tar-xzf"$PACKAGE"-C"$release_path"
ln-sfn"$release_path""$CURRENT_LINK"
log"已切换软链接:$CURRENT_LINK→$release_path"
}
restart_service(){
log"重启服务..."
ifsystemctlis-active--quiet"$APP_NAME"2>/dev/null;then
systemctlrestart"$APP_NAME"
sleep3
ifsystemctlis-active--quiet"$APP_NAME";then
log"服务重启成功"
else
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 招聘笔试之综合能力测试题及答案
- 业务员客户服务能力测试题及答案
- 知识产权宣传周活动试题及答案
- 幼儿园保健医面试常见问题及答案
- 中职第一学年(摩托车维修)摩托车发动机检修2026年阶段测试题及答案
- 2025年广西壮族自治区北海市三年级数学上册期中考试试卷及答案
- 2025年广西壮族自治区防城港市高一英语上册期中考试试卷及答案
- 2026年内蒙古数学小升初历年真题及答案
- 2026年内蒙古高职单招英语历年真题及答案
- 2025年广东省江门市四年级道德与法治上册期中考试试卷及答案
- 2025年冬季山东省高中学业水平合格考物理试卷(含答案)
- 备战2026年高考语文真题分类汇编(全国):专题10 文言文阅读(解析版)
- 湖南省长沙市长郡集团初中校2025-2026学年七年级上学期11月期中联考语文(含答案)
- 重症患者的体位管理
- 《AutoCAD 2021基础与应用案例教程》全套教学课件
- 2026华能山东石岛湾核电有限公司应届高校毕业生招聘笔试参考题库附答案解析
- 2025年中专无人机专业试题及答案
- 2025陇南市西和县辅警考试试卷真题
- JG/T 268-2019建筑用闭门器
- CJ/T 328-2010球墨铸铁复合树脂水箅
- 幼儿园中班科学语言《望着月亮吃大饼》课件
评论
0/150
提交评论