Shell-Script
在 shell 腳本中處理 64 位整數
我正在嘗試計算乙太網介面上使用的頻寬(即 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_bytes
或tx_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))
GNU
expr
可以支持任意精度的算術,如果它是用 GNU MP 庫建構的。在其他情況下,它使用本機整數,並且顯然在您的系統上(假設您使用的是 GNUexpr
)它們的大小為 32 位。其他實現可能有類似的限制。