次のようにサーバーの負荷平均を決定するスクリプトを作成しました。
#!/bin/bash
loadavg=`top -b -n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $2}'`
if [ "${loadavg}" -le 1 ]
then
echo "OK - Load Average = ${loadavg} | Load_Average=${loadavg}"
exit 0;
elif [ "${loadavg}" -gt 1 ] && [ "${loadavg}" -le 2 ]
then
echo "WARNING - Load Average = ${loadavg} | Load_Average=${loadavg}"
exit 1;
elif [ "${loadavg}" -gt 2 ]
then
echo "CRITICAL - Load Average = ${loadavg} | Load_Average=${loadavg}"
exit 2;
else
echo "UNKNOWN - Load Average = NaN | Load_Average=NaN"
fi
スクリプトを実行すると、次のエラーが表示されます。
./loadavg.sh
./loadavg.sh: line 5: [: 0.06: integer expression expected
./loadavg.sh: line 9: [: 0.06: integer expression expected
./loadavg.sh: line 13: [: 0.06: integer expression expected
UNKNOWN - Load Average = NaN | Load_Average=NaN
答え1
bash
ksh93
zsh
(または1とは逆)浮動小数点演算を実行できません。awk
しかし、そうです。ですべての操作を実行できますawk
。
top
また、ロードを受け取るためにを使用して1秒待つ必要はありません。ペイロードを得るための正式な方法はuptime
。
uptime | awk '{load=+$(NF-2)}
load > 2 {print "CRITICAL: " load; exit 2}
load > 1 {print "WARNING: " load; exit 1}
{print "OK: " load; exit 0}
END {if (!NR) {print "UNKNOWN"; exit 3}'
exit
1ただし、整数以外の値を比較するには、代替構文をzsh
使用する必要があります。(( loadavg > 2 ))
[ "$loadavg" -gt 2 ]
答え2
top -b -n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $2}'
nadaを返すので、エラーが発生します。
答え3
値loadavg
が空で構文エラーが発生します[
。
$ top -b n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $2}'
<blank line here>
次のように変更する必要があります。
$ top -b n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $1}'
0.24
ただし、この問題を解決するには、スクリプトで最新のテストを使用する必要があります。
$ [[ "" -gt 1 ]] || echo "OK"
OK
より古いもの[
:
$ [ "" -gt 1 ] || echo "OK"
bash: [: : integer expression expected
OK
修正する
bash
浮動小数点数は処理できないため、比較時に(新しいテストを実行しても[[..]]
)エラーが表示されます。
これを行うには、次のような他のツールを使用できますbc
。awk
例:
$ [[ $(echo "3 > 1" | bc -l) == 1 ]] && echo OK
OK
$[[ $(echo "3 < 1" | bc -l) == 1 ]] || echo Not OK
Not OK
答え4
第一に、ランニングトップは単に「稼働時間」を得るよりも費用がかかる。
$ uptime
16:15:38 up 6 days, 23:22, 23 users, load average: 0.99, 0.82, 0.70
第二に、@Stéphane Chazelasが述べたように、bashは浮動小数点演算を好まない。
$ [[ "0.1" -lt 1 ]]
bash: [[: 0.1: syntax error: invalid arithmetic operator (error token is ".1")
幸い bash 拡張機能を使用すると、この問題を解決できます。 ~から男乱交:
${parameter%word} ${parameter%%word} Remove matching suffix pattern. The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ``%'' case) or the longest matching pattern (the ``%%'' case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable sub- scripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.
したがって、「%.*」を使用して小数部を削除するのは非常に簡単です。
$ la=`uptime | sed 's/.*average: \([0-9\.]*\).*/\1/'`
$ if [ ${la%.*} -lt 1 ]; then echo "OK - Load average is $la"; fi
OK - Load average is 0.42