Вопрос или проблема
У меня есть следующий скрипт для проверки свободной памяти:
#!/bin/bash
THRESHOLD="500"
FREE_MEM=$(free -mh | awk '/^Mem:/{print $4}')
if [ "$FREE_MEM" -lt "$THRESHOLD" ]; then
echo "недостаточно памяти. Доступная память составляет ${FREE_MEM} MB"
fi
Однако я получаю эту ошибку:
./memory_monitor.sh: line 6: [: 135Mi: ожидается целочисленное выражение
На системе Ubuntu 24.04.1 LTS с 32 ГБ памяти команда free
, запущенная из скрипта, дает следующий результат:
$ free -mh | awk '/^Mem:/{print $4}'
25Gi
Обратите внимание, что использование опции h
(или --human
) приводит к тому, что вывод отображается в единицах гигабайт. Из man free
:
-h, --human
Показать все выходные поля, автоматически масштабируемые до самого короткого
трехзначного значения и отображать единицы вывода. Используются следующие единицы.
B = байты
Ki = кибибайты
Mi = мебибайты
Gi = гибибайты
Ti = тебибайты
Pi = пебибайты
Суффикс Gi
приведет к ошибке ожидается целочисленное выражение
.
Поэтому удалите опцию h
, чтобы получить значение в мебибайтах без суффикса. То есть:
#!/bin/bash
THRESHOLD="500"
FREE_MEM=$(free -m | awk '/^Mem:/{print $4}')
if [ "$FREE_MEM" -lt "$THRESHOLD" ]; then
echo "недостаточно памяти. Доступная память составляет ${FREE_MEM} MiB"
fi
Или, если вы хотите мегабайты (степень 1000), а не мебибайты (степень 1024), как подразумевает ваш MB
, используйте free --mega
вместо free -m
.
Как указывает ответ “Chester Gillon”, вам нужно использовать -m
без h
.
Вы также можете использовать $7
для вывода, потому что free
— это не доступная
память.
#!/bin/bash
THRESHOLD=500
FREE_MEM=$(free -m | awk '/^Mem:/{print $7}')
if [ "$FREE_MEM" -lt "$THRESHOLD" ]; then
echo "Недостаточно памяти. Доступная память составляет ${FREE_MEM} MiB"
else
echo "Достаточно памяти. Доступная память составляет ${FREE_MEM} MiB"
fi
В выводе free,
Свободная память — это количество памяти, которое в настоящее время не используется ни для чего. Эта цифра должна быть небольшой, потому что неиспользуемая память просто теряется.
Доступная память — это количество памяти, которое доступно для выделения новому процессу или существующим процессам.
Что такое доступная память при использовании команды free?
Что означает поле “доступно” в команде “free -m”
Что такое доступная и свободная память в ответ на команду free в Linux?
Ошибка заключается в этой строке:
FREE_MEM=$(free -mh | awk '/^Mem:/{print $4}')
потому что вы используете флаг -h
, который показывает значения в удобочитаемом формате и добавляет букву к числовому значению, например, 143M
вместо 143
.
Затем следующая строка вызывает ошибку:
if [ "$FREE_MEM" -lt "$THRESHOLD" ]; then
потому что она ожидает числовое значение в качестве первого аргумента.
Таким образом, скрипт нужно исправить следующим образом:
FREE_MEM=$(free -m | awk '/^Mem:/{print $4}')
Ответ или решение
Ошибка «Error parsing memory value in bash script: expected integer expression», с которой вы столкнулись в вашем bash-скрипте, является следствием того, что вы используете опцию -h
(читаемая человеком) при выполнении команды free
. Эта опция приводит к тому, что вывод команды содержит суффиксы для обозначения единиц измерения, таких как Mi
, Gi
и др. Это усложняет дальнейшую работу со значениями, поскольку операторы сравнения в bash ожидают числовых значений без суффиксов.
Анализ проблемы
Ваша строка, вызывающая ошибку, выглядит следующим образом:
FREE_MEM=$(free -mh | awk '/^Mem:/{print $4}')
С помощью этой команды вы пытаетесь получить количество свободной памяти, но опция -h
делает вывод в формате, который включает единицы измерения. Например, вместо чистого числа вы получаете выходные данные вроде 25Gi
, что и приводит к ошибке «integer expression expected» (ожидается целочисленное выражение) при попытке выполнить и сравнить значение.
Решения проблемы
Чтобы исправить эту ошибку, вам следует:
- Удалить опцию
-h
, чтобы получить значение без суффиксов. Это можно сделать следующим образом:
FREE_MEM=$(free -m | awk '/^Mem:/{print $4}')
Таким образом, при использовании -m
вы будете получать значение свободной памяти в мебибайтах (MiB) без каких-либо дополнительных символов.
- Сравнение значений: После изменения данной строки, ваш код будет выглядеть примерно так:
#!/bin/bash
THRESHOLD=500
FREE_MEM=$(free -m | awk '/^Mem:/{print $4}')
if [ "$FREE_MEM" -lt "$THRESHOLD" ]; then
echo "Недостаточно памяти. Доступная память составляет ${FREE_MEM} MiB"
else
echo "Достаточно памяти. Доступная память составляет ${FREE_MEM} MiB"
fi
Альтернативный подход
Если вам необходимо использовать значения в мегабайтах (по 1000 байт), вы также можете использовать команду free
с флагом --mega
:
FREE_MEM=$(free --mega | awk '/^Mem:/{print $4}')
Тем не менее, по умолчанию free -m
предоставляет удобные значения, учитывающие порядок 1024 (в мебибайтах).
Объяснение разницы между «свободной» и «доступной» памятью
Следует обратить внимание на различие между терминами «свободная» и «доступная» память. Свободная память — это количество памяти, которое в данный момент не используется. В то время как доступная память — это память, которая может быть перераспределена под новые процессы, и она быстрее доступна для использования. Ваша исходная строка могла возвращать неправильное значение (например, $4
для «свободной памяти»), когда значение по $7
представляло «доступную память» в выводе команды free
.
Вы можете изменить выбор столбца на awk
, чтобы получить значение доступной памяти, следующим образом:
FREE_MEM=$(free -m | awk '/^Mem:/{print $7}')
Заключение
С помощью простых изменений в вашем скрипте вы сможете избежать ошибок при работе с памятью в bash. Убедитесь, что вывод, с которым вы работаете, соответствует ожидаемому формату, а также уточните, какую именно память вы хотите контролировать — свободную или доступную. Эти изменения помогут вам создать более надежный скрипт для мониторинга памяти в системах Linux.