如何不清屏多行刷新变量输出?日志请求统计脚本优化
搞定Bash脚本固定表头、仅刷新请求计数的问题
嘿,你的脚本现在遇到的跳屏、无法固定输出的问题,主要是几个小细节没处理对,我帮你调整一下,实现固定表头只刷新数字的效果:
首先梳理下原脚本的核心问题:
- 计数变量只在脚本开头计算了一次,循环里一直用旧值,根本没更新实时数据
ssh $NODEIP只是单纯登录远程节点,没执行统计命令就退出来了,等于白跑- 光标移动的控制码用错了,导致每次都跳回屏幕顶部覆盖内容
- 还有
GETNAME未定义,BASEIP依赖的XIP应该是MYIP才对吧?
下面是修改后的完整脚本,直接就能用:
#!/usr/bin/bash # 初始化基础配置 MYIP=$(ifconfig eth1 | grep -w 'inet' | awk '{print $2}') BASEIP=$(echo "$MYIP" | cut -d"." -f-3) # 把节点名称和对应IP用数组管理,方便后续维护 NODES=("node-2" "node-3" "node-4") NODE_IPS=("$BASEIP.2" "$BASEIP.3" "$BASEIP.4") # 日志路径,确保所有节点都使用相同路径,或者改成你实际的日志路径 HTTPLOG="/var/log/httpd/access.log" # 先清屏,打印一次固定表头 clear printf "%15s\t%15s\t%15s\t%15s\t%15s\n" "Node" "PUT" "HEAD" "GET" "DELETE" # 开始循环刷新计数 while true; do # 逐个处理每个节点 for idx in "${!NODES[@]}"; do NODE_NAME="${NODES[$idx]}" NODE_IP="${NODE_IPS[$idx]}" # 通过ssh在远程节点执行统计命令,注意转义$防止本地解析 # 改用awk一次性统计所有请求类型,比多次grep更高效 read MONPUT MONHEAD MONGET MONDEL <<< $(ssh -n "$NODE_IP" " awk '\$9 ~ /20[0-9]/ {count[\$6]++} END {print count[\"PUT\"]+0, count[\"HEAD\"]+0, count[\"GET\"]+0, count[\"DELETE\"]+0}' $HTTPLOG ") # 用ANSI控制码定位到对应行(表头是第1行,节点从第2行开始) printf "\033[$((idx+2));0H" # 输出节点名称和最新计数 printf "%15s\t%15s\t%15s\t%15s\t%15s" "$NODE_NAME" "$MONPUT" "$MONHEAD" "$MONGET" "$MONDEL" done sleep 1 # 每秒刷新一次计数 done
核心修改说明:
- 固定表头:脚本启动时清屏并打印一次表头,之后再也不会修改表头位置
- 精准光标定位:用
\033[$行号;0H直接把光标移到对应节点行的开头,只覆盖该行的数字,不会跳回屏幕顶部 - 实时统计:每次循环都通过ssh去远程节点重新统计请求数,确保数据是最新的
- 高效统计:改用awk一次性统计所有请求类型,减少多次grep的开销,速度更快
- 节点管理:用数组存节点名称和IP,后续添加节点直接修改数组即可,不用调整循环逻辑
小提示:
- 确保所有节点都能无密码ssh登录,不然脚本会卡在输入密码环节
- 如果你的日志路径不是
/var/log/httpd/access.log,记得改成你实际的日志路径
内容的提问来源于stack exchange,提问作者Astroveny
相关产品推荐
相关产品推荐

