awk无法单独实时计算磁盘io服务速率,必须结合/proc/diskstats数据源、时间差计算和循环刷新机制;其作用限于解析、差值计算与格式化输出,需配合shell while循环和sleep实现后台巡检。

直接用 awk 单独“实时计算磁盘 IO 读写服务速率”并不现实——因为 awk 本身不采集数据,它只做文本处理。真正起作用的是底层指标源(如 /proc/diskstats)+ 时间差计算逻辑 + 循环刷新机制。awk 在这里扮演的是解析、差值计算和格式化输出的角色,需配合 while 循环和 sleep 才能实现“后台巡检”。
下面给出实用、低开销、无需 root 的方案,聚焦“服务速率”(即每秒完成的 I/O 操作数:IOPS),而非吞吐量(MB/s):
1. 理解核心指标来源:/proc/diskstats
/proc/diskstats 每行含 14 列,对单块磁盘(如 sda)关键列含义如下(按空格分隔):
- 第 4 列:读完成次数(
reads_completed) - 第 8 列:写完成次数(
writes_completed) - 第 3 列:读扇区数(512 字节/扇区)→ 可换算为 KB
- 第 7 列:写扇区数 → 同样可换算
⚠️ 注意:
/proc/diskstats是累计值,必须取两次快照、做差、除以时间间隔才能得“每秒速率”。
2. 用 awk + shell 实现后台巡检脚本(推荐)
以下脚本每 1 秒采样一次,输出 sda 的 读 IOPS、写 IOPS、读 KB/s、写 KB/s,后台运行且无依赖:
#!/bin/bash
DEV="sda"
INTERVAL=1
# 首次采样
read -r r1 w1 rk1 wk1 /dev/null)
[ -z "$r1" ] && { echo "设备 $DEV 未找到"; exit 1; }
while true; do
sleep "$INTERVAL"
read -r r2 w2 rk2 wk2 /dev/null)
[ -z "$r2" ] && continue
r_iops=$(( (r2 - r1) / INTERVAL ))
w_iops=$(( (w2 - w1) / INTERVAL ))
rk_per_sec=$(( (rk2 - rk1) * 512 / 1024 / INTERVAL )) # 转 KB/s
wk_per_sec=$(( (wk2 - wk1) * 512 / 1024 / INTERVAL ))
printf "%s | rIOPS=%d wIOPS=%d | rKB/s=%d wKB/s=%d\n" \
"$(date +%H:%M:%S)" "$r_iops" "$w_iops" "$rk_per_sec" "$wk_per_sec"
r1=$r2; w1=$w2; rk1=$rk2; wk1=$wk2
done
✅ 特点:
- 不依赖
iostat或sysstat,纯内核接口,容器里也能跑 - 输出带时间戳,适合日志留存或管道进监控系统(如
| grep 'wIOPS>1000') - 计算逻辑清晰,避免浮点(
awk做整数差值更稳)
3. 简化版单行命令(适合快速验证)
想一秒看当前速率?用这个组合(需两次采样,手动触发):
# 第一次快照(保存到文件)
awk '$3=="sda"{print $4,$8,$3,$7}' /proc/diskstats > /tmp/disk1
# 等 1 秒后第二次快照并计算
sleep 1
awk '$3=="sda"{print $4,$8,$3,$7}' /proc/diskstats | \
awk 'NR==FNR{r1=$1;w1=$2;rk1=$3;wk1=$4;next} {r2=$1;w2=$2;rk2=$3;wk2=$4; print "rIOPS:",(r2-r1), "wIOPS:",(w2-w1), "rKB/s:",int((rk2-rk1)*512/1024), "wKB/s:",int((wk2-wk1)*512/1024)}' /tmp/disk1 -
4. 如果你真要用纯 awk 循环(不推荐但可行)
GNU awk 支持 system("sleep 1") 和 BEGINFILE/ENDFILE,但跨平台兼容性差,且 sleep 在 awk 中阻塞不可控。更稳妥做法仍是 shell 控制节奏,awk 只管算——这是运维场景下的事实标准。
不复杂但容易忽略:/proc/diskstats 中设备名可能带前缀(如 nvme0n1 或 dm-0),务必用 lsblk -d -o NAME,TYPE | grep disk 确认真实设备名,再替换脚本中的 DEV。











