Я пытаюсь заставить скрипт что-то делать, когда одно число больше другого, в данном случае, когда средняя загрузка системы превышает определенное значение.
Все это работает помимо критериев оценки.
Пока я создаю еще один сервер для некоторых сайтов, я пытаюсь поддерживать apache в рабочем состоянии, причины не важны, но этот сценарий был протестирован и протестирован в системе, в которой средняя загрузка ниже 15 и сценарий распечатывает:
«check составляет 4.68, а max - 15.00» НЕСМОТРЯ на условие if, говорящее ему не печатать вообще ничего, если значение check не превышает max load, а это не так.
Я не гуру bash, у меня есть борода, но нет сандалий, и я пробовал использовать различные стили скобок и цитирования, но я не могу понять, почему этот скрипт вообще что-то печатает, когда $ check меньше $ max_load .
Это Debian 6, GNU bash, версия 4.1.5 (1) -release- (x86_64-pc-linux-gnu)
#!/bin/bash
check=`cat /proc/loadavg | sed 's/./ /' | awk '{print $2}'`
max_load='15.00';
high_load_log='/var/log/apache2/apache_high_load_restart.log';
apache_init='/etc/init.d/apache2';
if [[ $check > $max_load ]]; then
echo " check is $check and max is $max_load";
#$apache_init stop
sleep 5;
#$apache_init restart
echo "$(date) : Apache Restart due to load of | $check |" >> $high_load_log;
fi
В системе с загрузкой около 4 этот скрипт выводит:
"check is 4.68 and max is 15.00"
Кто-нибудь знает почему?
Любая помощь и предложения по поводу хороших сандалий для начинающих будут очень признательны!
Это не сработает. В >
оператор внутри [[
сравнивает Порядок сортировки, а не значение. Так....
$ echo -e '4.68\n15.00'|sort
15.00
4.68
... потому что 4 сортируются после 1, что означает [[ 4.68 > 15.00 ]]
правда. И ты не можешь использовать -gt
, потому что для этого нужны целые числа.
Если вас интересуют только целочисленные пороги, это легко исправить - усечь на .
, используйте -gt
, и вот так. В противном случае используйте bc
- видеть https://unix.stackexchange.com/questions/24721/how-to-compare-to-floating-point-number-in-a-shell-script
Спасибо всем, последнее решение, которое хорошо работает в моей системе Debian, заключалось в том, что сначала преобразовало его в int, а затем с помощью -gt.
#!/bin/bash
check=`cat /proc/loadavg | sed 's/ / /' | awk '{print $1}'`
checkint=${check/\.*}
max_load='20';
high_load_log='/var/log/apache2/apache_high_load_restart.log';
apache_init='/etc/init.d/apache2';
if [ $checkint -gt $max_load ]; then
echo " check is $checkint and max is $max_load";
$apache_init stop
sleep 5;
$apache_init restart
echo "$(date) : Apache Restart due to excessive load | $check |" >> $high_load_log;
else
echo "check is $check resolving down to $checkint and max is $max_load - No Action Taken";
fi
Согласно документам, <
, и >
площадь лексическая сортировка. Я не уверен, но я почти уверен, что это то же самое, что вы получили бы, если бы использовали что-то вроде sort
. С сортировкой, 15.00
раньше 4.68
потому что он в основном сортирует символы по символам. Так 1
раньше 4
в большинстве регионов.
Поскольку ваше примерное значение 4.68
будет после 15.0
лексически отсортированные, >
возвращает истину.
Вы почти наверняка хотели, чтобы ваши строки рассматривались как числа, поэтому вы должны использовать -gt
, или -lt
, но они ограничены целыми числами.
Ссылка: http://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html
строка1 <строка2 Истинно, если строка1 лексикографически сортируется перед строкой2.
строка1> строка2 Истинно, если строка1 лексикографически сортируется после строки2.
Основная проблема в том, что Bash поддерживает только целое число арифметика. Вы можете обойти это, используя инструмент, который поддерживает числа с плавающей запятой, что удобно в Awk.
(Я бы также исключил бесполезный cat
и обратите внимание, что sed | awk
аналогично бесполезно.)
awk -v max="$max_load" '$1 > max {
print "check is " $1 " and max is " max }' /proc/loadavg
Если вы хотите использовать это в условной оболочке, заставьте Awk возвращать нулевой код выхода в случае успеха и ненулевой в случае ошибки:
if ! check=$(awk -v max="$max_load" '($1 > max) {
print $1; exit 1 }' /proc/loadavg); then
echo " check is $check and max is $max_load";
$apache_init stop
sleep 5;
$apache_init restart
date +"%c : Apache Restart due to load of | $check |" >> $high_load_log;
fi