![오류: 정수 표현식이 필요합니다.](https://linux55.com/image/38464/%EC%98%A4%EB%A5%98%3A%20%EC%A0%95%EC%88%98%20%ED%91%9C%ED%98%84%EC%8B%9D%EC%9D%B4%20%ED%95%84%EC%9A%94%ED%95%A9%EB%8B%88%EB%8B%A4..png)
다음과 같이 서버의 로드 평균을 결정하는 스크립트를 작성했습니다.
#!/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