Bash 스크립트 오류: 정수 표현식이 필요합니다.

Bash 스크립트 오류: 정수 표현식이 필요합니다.

다소 이상한 문제가 발생했습니다. 여러 서버에서 스크립트(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 ))

usedtotal은 정수이므로 정수 bash산술이 이루어지지만 곱셈의 시프트는 처음부터 100입니다. 또는 올바른 반올림을 보장하려는 경우(계산의 "정수 나누기"는 항상 효과적으로 반올림됩니다):

result=$( printf '%.0f' $(echo "$used / $total * 100" | bc -l) )

이렇게 하면 에 후행 점이 없는지 확인할 수 있습니다 result. 사용된 방법은 cut10-99 범위의 결과에만 작동하므로 좋은 생각이 아닙니다. result귀하의 경우와 같이 0-9 및 99 이상의 숫자에 대해서는 실패 합니다.

업데이트 2

~에서@Stephane의 의견은 다음과 같습니다, 임계값과 비교할 때는 반올림하는 것이 가장 좋습니다. 이를 염두에 두고 질문의 코드 조각에 또 다른 작은 버그가 있습니다. 및 에 사용된 warn_level비교 간의 불일치에 유의하세요 critical_level. 비교는 warn_level정확하지만 (그냥 작음) 대신 (작거나 같음)을 critical_level사용하세요 . 다음보다 약간 큰 경우를 고려하세요 . 반올림 해야 하지만 중요한 경고가 발생하지 않습니다( 비교가 사용된 경우 발생함).-le-ltresultcritical_levelcritical_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적으로 발생하므로 중복되므로 제거되었습니다.elifelse

답변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오류가 발생하지 않습니다.result1if

cut -c -2오류가 발생하는 이유 는 주로 처음 두 문자만 잘리기 때문인 것 같습니다 . 결과가 단 하나의 문자라면 어떻게 될까요? 결과가 다음과 같다고 가정하면 1.23456위의 잘라내기 결과는 분명히 오류를 일으키는 1.값이 됩니다 .resultinteger 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

관련 정보