다소 이상한 문제가 발생했습니다. 여러 서버에서 스크립트(Bash)를 실행 중인데 그 중 하나에서 작동이 중지되었습니다(다른 모든 서버에서는 제대로 작동함).
스크립트에서 문제가 되는 부분은 다음과 같습니다. (내가 직접 쓴 것은 아니며 모든 크레딧은 "Rich"로 이동합니다.)(http://www.notrainers.org/monitoring-memory-usage-on-linux-with-nagios-and-nrpe/)
if [ "$result" -lt "$warn_level" ]; then #Line 56
echo "Memory OK. $result% used."
exit 0;
elif [ "$result" -ge "$warn_level" ] && [ "$result" -le "$critical_level" ]; then #Line 59
echo "Memory WARNING. $result% used."
exit 1;
elif [ "$result" -gt "$critical_level" ]; then #Line 62
echo "Memory CRITICAL. $result% used."
exit 2;
fi
전체 오류 메시지:
./check_memory.sh: Line 56: [: 7.: integer expression expected
./check_memory.sh: Line 59: [: 7.: integer expression expected
./check_memory.sh: Line 62: [: 7.: integer expression expected
더 많은 정보가 필요하시면 알려주시면 최대한 빨리 제공하도록 노력하겠습니다.
모든 의견을 보내주셔서 감사합니다 :)
답변1
겉보기에 result
변수 .
뒤에 숫자가 있어서 bash에서 인식할 수 없습니다. 다음을 수행하여 오류를 재현할 수 있습니다.
[ 7. -gt 1 ]
질문에 더 많은 스크립트를 추가하면 이 내용이 어디서 나오는지 제안해 드릴 수 있습니다.
고쳐 쓰다
전체 스크립트를 보면 다음 줄을 대체했습니다.
result=$(echo "$used / $total * 100" |bc -l|cut -c -2)
그리고:
result=$(( 100 * used / total ))
used
합 total
은 정수이므로 정수 bash
산술이 이루어지지만 곱셈의 시프트는 처음부터 100입니다. 또는 올바른 반올림을 보장하려는 경우(계산의 "정수 나누기"는 항상 효과적으로 반올림됩니다):
result=$( printf '%.0f' $(echo "$used / $total * 100" | bc -l) )
이렇게 하면 에 후행 점이 없는지 확인할 수 있습니다 result
. 사용된 방법은 cut
10-99 범위의 결과에만 작동하므로 좋은 생각이 아닙니다. result
귀하의 경우와 같이 0-9 및 99 이상의 숫자에 대해서는 실패 합니다.
업데이트 2
~에서@Stephane의 의견은 다음과 같습니다, 임계값과 비교할 때는 반올림하는 것이 가장 좋습니다. 이를 염두에 두고 질문의 코드 조각에 또 다른 작은 버그가 있습니다. 및 에 사용된 warn_level
비교 간의 불일치에 유의하세요 critical_level
. 비교는 warn_level
정확하지만 (그냥 작음) 대신 (작거나 같음)을 critical_level
사용하세요 . 다음보다 약간 큰 경우를 고려하세요 . 반올림 해야 하지만 중요한 경고가 발생하지 않습니다( 비교가 사용된 경우 발생함).-le
-lt
result
critical_level
critical_level
-lt
큰 문제는 아닐 수도 있지만 수정된 코드는 다음과 같습니다.
if [ "$result" -lt "$warn_level" ]; then
echo "Memory OK. $result% used."
exit 0;
elif [ "$result" -lt "$critical_level" ]; then
echo "Memory WARNING. $result% used."
exit 1;
else
echo "Memory CRITICAL. $result% used."
exit 2;
fi
이러한 테스트는 도착 시 암시 -ge
적으로 발생하므로 중복되므로 제거되었습니다.elif
else
답변2
제공하신 링크에서 다음 줄을 볼 수 있습니다.
result=$(echo "$used / $total * 100" |bc -l|cut -c -2)
@Graeme의 의견에 따라 위 줄을 아래 줄로 변경합니다.
result=$(echo "$used / $total * 100" |bc -l)
result
이제 위의 줄을 추가한 후 아래와 같이 출력을 정수로 변경해야 합니다 .
result1=${result/.*}
나는 오류가 발생한 한 컴퓨터에서 이 출력이 정수가 아니라고 추측합니다. 이러한 경우를 처리하려면 결과 출력을 정수로 변환하면 됩니다. 계산 후에 다음 줄을 추가합니다 result
.
result1=${result/.*}
루프 내에서 변수 이름을 변경하는 대신 result
오류가 발생하지 않습니다.result1
if
cut -c -2
오류가 발생하는 이유 는 주로 처음 두 문자만 잘리기 때문인 것 같습니다 . 결과가 단 하나의 문자라면 어떻게 될까요? 결과가 다음과 같다고 가정하면 1.23456
위의 잘라내기 결과는 분명히 오류를 일으키는 1.
값이 됩니다 .result
integer expected
result
나머지 서버에서 잘 작동하는 이유는 변수에 숫자가 하나만 있는 상황이 발생하지 않기 때문입니다. 결과가 한 자리 변수인 경우(위의 예에서 언급한 것처럼) 나머지 서버에서도 실패할 가능성이 높습니다.
답변3
awk
그래서 잘 활용하는 방법을 전혀 모르겠습니다. 그러나 나는 당신이 연결한 스크립트에 많은 쓰레기가 일어나고 있다는 것을 알고 있으며 다음과 같은 것이 작동해야 합니다. 죄송합니다. 완벽하게 작성할 수는 없지만 두 번 호출했으므로 awk
다음과 같이 사용해야 할 것 같습니다.
_chkmem() { return $(
free -m | grep "buffers/cache"
awk '{
percent = ( $3 / ( $3 + $4 ) ) * 100
warn = '"${warnlevel?No warning level specified!}"' < percent ? WARNING : OK
crit = '"${critical?No critical level specified!}"' < percent ? CRITICAL : $warn
print "Mem $crit : $percent% used"
if ( $crit != OK ) exit 1
}')
}
_chkmem || exit 1