shell脚本之获取实时网卡吞吐流量
前言
本文会是一个系列,每次介绍一个对运维人员较为实用的shell脚本。
实现功能
获取网卡的实时流量。(本脚本在centos6.9/7.5下实测通过)
实现思路
分别获取网卡上行和下行数据
网卡流量数据信息可以使用ip -s link命令获取,但现在的主机很可能有多张网卡,比如做了bonding(端口绑定)的网卡,其真实数据在一张虚拟网卡上,所以我们的第一步工作是确认真实的数据在哪一张网卡上。
1.1 获取有真实数据的网卡。
通过 ip route命令,会以行方式显示系统路由表,并且每一行都会有某条路由对应的网卡名。其中默认路由有一个关键字default,类似如下:
[root@badteacher ~]# ip routedefault via 172.27.0.1 dev eth0 169.254.0.0/16 dev eth0 scope link metric 1002 172.27.0.0/20 dev eth0 proto kernel scope link src 172.27.0.14
我们想要的数据是default行的网卡的名称eth0,观察此行,发现内容以空格分开,分为5列,我们要的网卡名在第5列。
ip route | grep default | awk -F ' ' {'print $5'}
1.2 获取对应网卡的上下行数据
[root@badteacher ~]# ip -s link ls eth02: eth0:
执行ip -s link ls eth0命令,我们想要的数据出现了,现在想办法提取出来。
通过观察,发现上行数据(Rx)固定出现在倒数第三行的第1列。
ip -s link ls $cardName | tail -n 3 | head -n 1 | awk {'print $1'}
tail -n 3取出倒数3行,head -n 1取出第1行,awk {'print $1'},输出第1列内容。这样就得到了上行数据。下行数据方法类似,只是下行数据(Tx)的数据出现在倒数第一行。
ip -s link ls $cardName | tail -n 1 | awk {'print $1'}
现在获取的数据是网卡已接收/发送的总字节数,是不能直接计算的。我们需要的数据是每秒网卡上下行流量。根据命令的特性,我们需要隔1秒再次采集网卡的上下行流量。
sleep 1
这个命令是让shell睡眠一秒(不做任何动作),然后再次获取网卡的上/下行流量,将当前获取的上/下行流量数据减去之前获取的上/下行数据,就得到了真实的流量数据。
realRxBytes=$(((curRxBytes - prevRxBytes) / 1024 / 1024 ))
因为单位是bytes,本例想以Mbytes为单位,需要除以2次1024。
2. 呈现数据
echo in:${realRxBytes}M echo out:${realTxBytes}M
脚本代码
#!/bin/bash#定义了一个名为getBytes的函数getBytes() {#此条命令的目的是获取承载系统默认路由的网卡名称。cardName=$(ip route | grep default | awk -F ' ' {'print $5'})#获取当前系统已接收的字节数prevRxBytes=$(ip -s link ls $cardName | tail -n 3 | head -n 1 | awk {'print $1'})#获取当前系统已发送的字节数prevTxBytes=$(ip -s link ls $cardName | tail -n 1 | awk {'print $1'})#让shell睡眠1秒sleep 1#再次获取当前系统已接收的字节数curRxBytes=$(ip -s link ls $cardName | tail -n 3 | head -n 1 | awk {'print $1'})#获取实际上行(in)流量,公式为当前已接收字节数-1秒前已接收字节数,得到的数字以字节为单位,#除以1次1024后单位为Kbytes,再除以1次1024后单位为Mbytes。realRxBytes=$(((curRxBytes - prevRxBytes) / 1024 / 1024 ))#再次获取当前系统已发送的字节数curTxBytes=$(ip -s link ls $cardName | tail -n 1 | awk {'print $1'})#获取实际下行(out)流量,公式和上行流量类似realTxBytes=$(((curTxBytes - prevTxBytes) / 1024 / 1024))#向屏幕输出结果echo in:${realRxBytes}Mecho out:${realTxBytes}M}#让shell支持参数,t表示用户如果在命令行下使用了参数t,例如:./test.sh -t,会将这个参数以$ARGS的方式传递给shell。while getopts t ARGSdo#通过case来为不同参数执行不同功能case $ARGS in#如果用户输入的参数为t,执行里面的代码t)#开始一个“死循环”while [ 1 ]do#调用getBytes函数getBytesdone##表示语句结束;;#case结束标志esacdone#如果执行shell时未选择参数,执行此命令getBytes
shell脚本是Linux运维人员必需掌握的武器,有了它,能让我们的运维效率有显著的提高,借此,希望我们一起学习并分享经验,共同进步。
如果你对讲解的shell有疑问,请通过评论告诉我,我会尽可能快的回复。笔者的水平也有限,如果你发现什么bug,也请告诉我,我会尽快改正。
查看原文 >>