Answers:
做到这一点的最佳方法可能就是解析/proc/net/dev
(警告它/proc
不可移植)。这是bash
我快速整理的脚本,应该可以计算出来:
#!/bin/bash
_die() {
printf '%s\n' "$@"
exit 1
}
_interface=$1
[[ ${_interface} ]] || _die 'Usage: ifspeed [interface]'
grep -q "^ *${_interface}:" /proc/net/dev || _die "Interface ${_interface} not found in /proc/net/dev"
_interface_bytes_in_old=$(awk "/^ *${_interface}:/"' { if ($1 ~ /.*:[0-9][0-9]*/) { sub(/^.*:/, "") ; print $1 } else { print $2 } }' /proc/net/dev)
_interface_bytes_out_old=$(awk "/^ *${_interface}:/"' { if ($1 ~ /.*:[0-9][0-9]*/) { print $9 } else { print $10 } }' /proc/net/dev)
while sleep 1; do
_interface_bytes_in_new=$(awk "/^ *${_interface}:/"' { if ($1 ~ /.*:[0-9][0-9]*/) { sub(/^.*:/, "") ; print $1 } else { print $2 } }' /proc/net/dev)
_interface_bytes_out_new=$(awk "/^ *${_interface}:/"' { if ($1 ~ /.*:[0-9][0-9]*/) { print $9 } else { print $10 } }' /proc/net/dev)
printf '%s: %s\n' 'Bytes in/sec' "$(( _interface_bytes_in_new - _interface_bytes_in_old ))" \
'Bytes out/sec' "$(( _interface_bytes_out_new - _interface_bytes_out_old ))"
# printf '%s: %s\n' 'Kilobytes in/sec' "$(( ( _interface_bytes_in_new - _interface_bytes_in_old ) / 1024 ))" \
# 'Kilobytes out/sec' "$(( ( _interface_bytes_out_new - _interface_bytes_out_old ) / 1024 ))"
# printf '%s: %s\n' 'Megabits in/sec' "$(( ( _interface_bytes_in_new - _interface_bytes_in_old ) / 131072 ))" \
# 'Megabits out/sec' "$(( ( _interface_bytes_out_new - _interface_bytes_out_old ) / 131072 ))"
_interface_bytes_in_old=${_interface_bytes_in_new}
_interface_bytes_out_old=${_interface_bytes_out_new}
done
请记住,sleep
没有考虑在while循环中执行操作所花费的时间,因此(非常轻微)这是不准确的。在我的600mhz铜矿上,循环需要0.011秒-对于大多数用途而言,这种误差可以忽略不计。当使用(注释)千字节/兆位输出时,请记住,bash仅理解整数算术。
date +%s.%N
获得UNIX时间戳每次迭代和除以时间戳差异字节的差异。这样就避免了循环迭代超过1s的问题。
这是一个非常简单的shell脚本来计算:
#!/bin/sh
dev=$1
grep -q "^$dev:" /proc/net/dev || exec echo "$dev: no such device"
read rx <"/sys/class/net/$dev/statistics/rx_bytes"
read tx <"/sys/class/net/$dev/statistics/tx_bytes"
while sleep 1; do
read newrx <"/sys/class/net/$dev/statistics/rx_bytes"
read newtx <"/sys/class/net/$dev/statistics/tx_bytes"
# convert bytes to kbit/s: bytes * 8 / 1000 => bytes / 125
echo "$dev {rx: $(((newrx-rx) / 125)), tx: $(((newtx-tx) / 125))}"
rx=$newrx
tx=$newtx
done
只需启动传递接口名称的脚本即可,例如。 ./shtraf eth1
/proc/net/dev
而没有真正了解这种魔术的作用和发生方式。