Ошибка арифметики BC

Следуйте дальнейшим инструкциям в файле readme:

Смонтируйте драйвер, перейдите в каталог драйвера и выполните:

[root@localhost template]# modprobe usbnet   
[root@localhost template]# insmod ax88179_178a.ko   

Если вы хотите выгрузить драйвер:

[root@localhost anywhere]# rmmod axax88179_178a

или навсегда:

[root@localhost template]# make install

Мне не нужно было скомпилировать что угодно, файл .ko был сгенерирован автоматически, мне просто нужно было смонтировать драйвер, и он заработал! Я боялся менять ядро ​​вручную, но в этом не было необходимости.

0
29.10.2018, 13:25
3 ответа

awkможет выполнять все работы read, cut, grepи bcздесь:

 awk -F': *' '
   $1 == "MemTotal" {t = $2}
   $1 == "MemFree" {f = $2}
   END {printf "%.1f%%\n", (t - f) * 100 / t}' /proc/meminfo

Имейте в виду, что не все awkреализации будут выводить 40,5% вместо 40,5 в локалях, где запятая используется в качестве десятичной системы счисления (GNU awkделает это только в режиме POSIX, например, когда $POSIXLY_CORRECTнаходится в окружающая среда ). Используйте LC_ALL=C awk..., чтобы установить десятичную систему счисления с точкой/точкой.

Измените %.1fна %.0f, если вы вообще не хотите использовать десятичную часть. Это округлит до ближайшего целого числа. Вместо этого используйте %d, если вы хотите усечь десятичную часть (, чтобы получить 99% вместо 100% для 99,999 ).

Ваш read t f <<< `grep -E 'Mem(Total|Free)' /proc/meminfo |awk '{print $2}'`работал бы в более старых версиях bashпри немодифицированном $IFS.

В cmd <<< `code`, bashиспользуется для разделения вывода codeна символы $IFS(, которые по умолчанию включают новую строку ), и их соединения с первым символом$IFS(по умолчанию через пробел ). ] перед подачей в качестве стандартного ввода для команды. Таким образом, в вашем случае эти две строки вывода awkв конечном итоге -будут поданы как два слова в одной строке, как и ожидалось read t f. Это удивительное поведение (, а также отличающееся от исходной реализации в zsh), было исправлено в bash -4.4.

В bash-4.4и более поздних версиях вам потребуется{ read t; read f; } <<< "$(awk...)"(с добавлением кавычек вокруг $(...), чтобы он также работал в bash -4.3 и более ранних версиях, по-прежнему принимая значение по умолчанию$IFS).

3
28.01.2020, 02:18

Строка, считанная командой read, содержит только 1 поле, где 2 должны заполнить обе переменные tи f.

Вы можете решить эту проблему, добавив | tr '\n' ' 'после команды awk.

Но было бы лучше упростить его до:

read t f <<< $(awk '/MemTotal/{t=$2}/MemFree/{f=$2}END{print t,f}' /proc/meminfo)
0
28.01.2020, 02:18

Аннотация:

Portable, в одну строку и с использованием printf:

awk '/MemTotal/{t=$2}; /MemFree/{f=$2}; END{printf("%d\n",(1-f/t)*100)}'

Только Шелл (Баш):

memused() { : # Print the (integer) value of % of free memory
            local ret ref a t f 
            ret='MemTotal:[ \t]*([0-9]+)';              # Regex for Total memory.
            ref='MemFree:[ \t]*([0-9]+)';               # Regex for Free  memory.
            a=$(</proc/meminfo)                         # Get meminfo in var (a).
            [[ $a =~ $ret ]] && t="${BASH_REMATCH[1]}"  # Get Total memory.
            [[ $a =~ $ref ]] && f="${BASH_REMATCH[1]}"  # Get Free  memory.
            printf '%s\n' "$(( 100 - 100*f/t )) %"      # Print integer % value.
          }

Описание

Причина жалобы bc в том, что он получает только одну переменную.

Для воспроизведения:

$ t=150 ; f='' ; bc <<< "scale=2; 100 - $f / $t * 100"
(standard_in) 1: syntax error

Один из способов избежать этой ошибки — установить значение по умолчанию:

$ t=150; f=''; bc <<< "scale=2; 100 - ${f:-0} / ${t:-0} * 100"
100

Причина только одного значения заключается в том, что чтение получает значения в отдельных строках (в bash 4.4 ). Решение, которое хорошо работает для всех версий bash, заключается в использовании-d '':

$ read -d '' t f <<< "`grep -E 'Mem(Total|Free)' /proc/meminfo |awk '{print $2}'`"
$ echo "total=<$t>     free=<$f>"
total=<1922764>     free=<424360>

И это также работает независимо от того, заключено ли расширение команды в кавычки (, как должно быть )"`grep … '`", или нет.

Но нет причин вызывать grep, awk, bcи, наконец, cut. Один вызов awk может сделать все это:

</proc/meminfo awk '/MemTotal/{t=$2}
                    /MemFree/ {f=$2}
                    END{
                        print( (1-f/t)*100 )
                    }
                   '

В одну строку и с помощью printf:

awk '/MemTotal/{t=$2};/MemFree/{f=$2};END{printf("%d\n",(1-f/t)*100)}' </proc/meminfo

Если вы хотите, чтобы что-то работало быстрее и использовало только оболочку (, хотя и bash):

memused() {  : # Print the (integer) value of % of free memory
             local ret ref a t f 
             ret='MemTotal:[ \t]*([0-9]+)';              # Regex for Total memory.
             ref='MemFree:[ \t]*([0-9]+)';               # Regex for Free  memory.
             a=$(</proc/meminfo)                         # Get meminfo in var (a).
             [[ $a =~ $ret ]] && t="${BASH_REMATCH[1]}"  # Get Total memory.
             [[ $a =~ $ref ]] && f="${BASH_REMATCH[1]}"  # Get Free  memory.
             printf '%s\n' "$(( 100 - 100*f/t )) %"      # Print integer % value.
   }
1
28.01.2020, 02:18

Теги

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