You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell脚本调用vnstat获取带宽数据无输出及输出格式异常问题求助

Shell脚本调用vnstat获取带宽数据无输出及输出格式异常问题求助

我完全理解你作为非Shell脚本开发者,碰到这种数据提取和格式转换的问题有多头疼!咱们先拆解你原脚本里的问题,再给你一个更可靠的修复版本。

原脚本的核心问题

  1. 完全依赖固定行号和字段位置:vnstat的输出行数会随着显示的小时数变化,固定用tail -n2、tail -n9或者$11提取字段,很容易因为输出格式变化(比如终端宽度、vnstat版本更新)拿到空值或者错误数据。
  2. 数值处理逻辑错误:如果你的系统是欧洲 locale,vnstat的数值会用逗号做小数点(比如1,23),原脚本把逗号分割的两部分直接拼接成123,完全破坏了浮点数格式。
  3. 单位提取不可靠:从固定行里抠单位的方式太脆弱,一旦输出结构变了就彻底失效。
  4. 没处理空值情况:如果vnstat还没生成统计数据,你的脚本会拿着空值继续计算,结果自然异常。
  5. 比特/字节转换遗漏:vnstat的平均速率单位通常是kbit/s这类比特单位,原脚本直接乘以1024,没考虑1字节=8比特的转换,结果会差8倍!

修复后的脚本

这个版本更健壮,能适配大多数vnstat输出场景,还处理了空值和格式问题:

# 提取最新小时的统计行,排除掉最后一行的"estimated"预估数据
latest_hour_line=$(vnstat -h | grep -v "estimated" | tail -n1)

# 从该行提取速率数值和单位:倒数第二个字段是数值,最后一个是单位
# 把数值里的逗号(欧洲小数点)替换成点,确保bc能识别为浮点数
rate_value=$(echo "$latest_hour_line" | awk '{gsub(/,/, ".", $(NF-1)); print $(NF-1)}')
rate_unit=$(echo "$latest_hour_line" | awk '{print $NF}')

# 检查是否成功提取到数值,空值直接报错退出
if [ -z "$rate_value" ]; then
    echo "错误:无法获取vnstat带宽数据,请检查vnstat是否已启动并生成统计"
    exit 1
fi

# 将速率转换为每秒字节数(注意区分比特和字节单位)
case "$rate_unit" in
    kbit/s)
        # kbit/s转字节:1kbit = 1024比特,1字节=8比特
        bandwidth_out_number_Byte=$(echo "scale=2; $rate_value * 1024 / 8" | bc)
        ;;
    Mbit/s)
        bandwidth_out_number_Byte=$(echo "scale=2; $rate_value * 1024 * 1024 / 8" | bc)
        ;;
    Gbit/s)
        bandwidth_out_number_Byte=$(echo "scale=2; $rate_value * 1024 * 1024 * 1024 / 8" | bc)
        ;;
    KiB/s)
        bandwidth_out_number_Byte=$(echo "scale=2; $rate_value * 1024" | bc)
        ;;
    MiB/s)
        bandwidth_out_number_Byte=$(echo "scale=2; $rate_value * 1024 * 1024" | bc)
        ;;
    GiB/s)
        bandwidth_out_number_Byte=$(echo "scale=2; $rate_value * 1024 * 1024 * 1024" | bc)
        ;;
    *)
        echo "错误:不支持的单位 $rate_unit"
        exit 1
        ;;
esac

# 输出最终结果
echo "转换后的每秒带宽字节数:$bandwidth_out_number_Byte"

脚本说明

  • 可靠的行提取:用grep -v "estimated"排除预估行,再取最后一行,不管vnstat显示多少小时,都能拿到最新的统计数据。
  • 自适应字段提取:用$NF(最后一个字段)和$(NF-1)(倒数第二个字段)提取单位和数值,不依赖固定字段序号,适配不同输出格式。
  • 数值格式修复:自动把逗号小数点转成点,确保后续计算能得到正确的浮点数。
  • 空值检查:提前判断是否提取到数据,避免无效计算。
  • 正确的单位转换:区分比特和字节单位,转换逻辑符合标准,不会出现数值偏差。

备注:内容来源于stack exchange,提问作者islam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 10:44:53