Обработка 64 -битных целых чисел в сценарии оболочки

У меня только что была эта (мышь, которая может двигаться, но щелчки ничего не делают ).

Я понял, что в фоновом режиме окно программы закрывалось слишком медленно, а Gnome показывал всплывающее окно с запросом «Принудительно закрыть» или «Подождите».

В моем случае приведенная ниже процедура освободила мою мышь:

  1. Перейти к этому всплывающему окну с помощью ALT -TAB
  2. Выберите параметр с помощью TAB
  3. Нажмите Enter
7
24.06.2021, 18:17
3 ответа

Учитывая, что 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))

GNUexprможет поддерживать произвольную -точность арифметики, если она построена с библиотекой GNU MP . В других случаях он использует собственные целые числа, и, по-видимому, в вашей системе (при условии, что вы используете GNU expr), они имеют размер 32 бита. Другие реализации, вероятно, имеют аналогичные ограничения.

17
28.07.2021, 11:22

bashиспользует 64-битные целые числа:

$echo $((2**63-1))
9223372036854775807
$echo $((2**63))
-9223372036854775808
7
28.07.2021, 11:22

Стандартным калькулятором произвольной -точности является 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 ), полезный для деления на десятичные или двоичные тысячи. Он способен работать с очень большими числами (, хотя, по общему признанию, это не странная смесь, используемая здесь ).

3
28.07.2021, 11:22

Теги

Похожие вопросы