イーサネットインターフェイスで使用される帯域幅(1000 Mbit / s)を計算しようとしています。私のスクリプトをテストするために使用します。アイパフ膨大な帯域幅を生成するツール。
私が直面している問題は、最大32ビット値より大きい値をいつどのように取得できるかということeth0_rx1
です。eth0_rx2
私はゼロの違いを得る。
何とか
printf 'eth0 Download rate: %s B/s\n' "$((eth0_rx2-eth0_rx1))"
正しい値を提供しますが、使用しようとすると
eth0_diff=expr $eth0_rx2 - $eth0_rx1
私が得る値はゼロです。
32ビットrx_bytes
以上の場合に処理する方法はありますか?tx_bytes
これが使用された帯域幅を計算するエレガントな方法であるかどうかはわかりません。そうでない場合は、別の選択肢を提案してください。
出力例:
eth0_rx1 = 2134947002 \
eth0_rx2= 2159752166 \
eth0 Download rate: 24805164 B/s \
eth0_diff = 12536645 \
eth0_rx_kB = 12242 \
eth0_rx_kB_100 = 1224200 \
eth0_rx_kB_BW = 9
eth0_rx1 = 2159752166 \
eth0_rx2= 2184557522 \
eth0 Download rate: 24805356 B/s \
eth0_diff = 0 \
eth0_rx_kB = 0 \
eth0_rx_kB_100 = 0 \
eth0_rx_kB_BW = 0
使用されたスクリプト:
#!/bin/sh
eth0_rx1=$(cat /sys/class/net/eth0/statistics/rx_bytes)
while sleep 1; do
eth0_rx2=$(cat /sys/class/net/eth0/statistics/rx_bytes)
echo "eth0_rx1 = $eth0_rx1"
echo "eth0_rx2= $eth0_rx2"
printf 'eth0 Download rate: %s B/s\n' "$((eth0_rx2-eth0_rx1))"
eth0_diff=`expr $eth0_rx2 - $eth0_rx1`
echo "eth0_diff = $eth0_diff"
#convert bytes to Kilo Bytes
eth0_rx_kB=`expr $eth0_diff / 1024`
echo "eth0_rx_kB = $eth0_rx_kB"
#bandwidth calculation
eth0_rx_kB=`expr $eth0_rx_kB \* 100`
echo "eth0_rx_kB_100 = $eth0_rx_kB"
#125000 = 1000 Mbit/s
eth0_rx_kB=`expr $eth0_rx_kB / 125000`
echo "eth0_rx_kB_BW = $eth0_rx_kB"
eth0_rx1=$eth0_rx2
eth2_rx1=$eth2_rx2
done
答え1
正しい値が与えられたと仮定し、printf 'eth0 Download rate: %s B/s\n' "$((eth0_rx2-eth0_rx1))"
整数演算で十分であれば、次の答えを得ることができます$((eth0_rx2-eth0_rx1))
。つまり シェル算術。
多くのシェル、特にBashは以下を使用します。64ビット整数、32ビットプラットフォームでも同様です。
したがって:
eth0_diff=$((eth0_rx2 - eth0_rx1))
...
eth0_rx_kB=$((eth0_diff / 1024))
...
eth0_rx_kB=$((eth0_rx_kB * 100))
...
eth0_rx_kB=$((eth0_rx_kB / 125000))
牛に似た一種の栄養expr
できる任意の精密演算をサポートします。GNU MPライブラリでビルドされた場合。それ以外の場合は、expr
システムはサイズが明らかに32ビットのデフォルトの整数を使用します(GNUを使用していると仮定)。他の実装にも同様の制限があるかもしれません。
答え2
bash
64ビット整数を使用してください。
$echo $((2**63-1))
9223372036854775807
$echo $((2**63))
-9223372036854775808
答え3
標準任意精度計算機ですdc
。これを使用して大きな整数演算を実行できます。
eth0_diff=$(dc -e "$eth0_rx2 $eth0_rx1 -p")
dc
とコマンドを使用して印刷することもできます。n
p
#!/bin/sh
set -eu
netstatfile=/sys/class/net/eth0/statistics/rx_bytes
test -r "$netstatfile"
eth0_rx1=$(cat "$netstatfile")
while sleep 1
do
eth0_rx2=$(cat "$netstatfile")
dc -e "$eth0_rx1[eth0_rx1 = ]np $eth0_rx2[eth0_rx2 = ]np" \
-e 'r-[eth0_diff = ]np [Download rate: ]np 1024/[eth0_rx_kB = ]np' \
-e '100/[eth0_rx_kB_100 = ]np 125000/[eth0_rx_kB_BW = ]np'
eth0_rx1=$eth0_rx2
done
このnumfmt
ツール(GNU coreutilsの一部)は、10進数または2進数の布に分割するのに役立ちます。非常に大きな数字を扱うことができます(もちろん、ここで使用されている奇妙な混合ではありませんが)。