Shell-Script

在 shell 腳本中處理 64 位整數

  • June 24, 2021

我正在嘗試計算乙太網介面上使用的頻寬(即 1000 Mbit/s)。為了測試我的腳本,我使用iperf工具來生成巨大的頻寬。

我面臨的問題是何時eth0_rx1獲取eth0_rx2大於最大 32 位值的值。我得到的差異為0。

不知何故

printf 'eth0 Download rate: %s B/s\n' "$((eth0_rx2-eth0_rx1))"

給出了正確的值,但是當嘗試使用

eth0_diff=expr $eth0_rx2 - $eth0_rx1

我得到的值為 0。

有沒有辦法處理是否rx_bytestx_bytes超過 32 位?

我不確定這是一種計算已用頻寬的優雅方法。如果沒有,請建議其他替代方式。

樣本輸出:

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

鑑於這printf 'eth0 Download rate: %s B/s\n' "$((eth0_rx2-eth0_rx1))"給了您正確的值,只要整數算術足夠好,您就會得到答案:$((eth0_rx2-eth0_rx1)) shell 算術

許多 shell,尤其是 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))

GNUexpr 可以支持任意精度的算術,如果它是用 GNU MP 庫建構的。在其他情況下,它使用本機整數,並且顯然在您的系統上(假設您使用的是 GNU expr)它們的大小為 32 位。其他實現可能有類似的限制。

引用自:https://unix.stackexchange.com/questions/655470