배쉬 스크립트 오류 : 정수 식 예상


13

다소 이상한 문제가 있는데 여러 서버에서 스크립트 (Bash)를 실행 중이며 서버 중 하나에서 작동이 중지되었습니다 (다른 모든 서버에서 완벽하게 작동).

다음 스크립트의 문제 부분은 다음과 같습니다 ((내가 나 자신을 작성하지 않은 모든 학점은 "리치"로 이동) 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

더 많은 정보가 필요하면 알려 주시면 최대한 빨리 정보를 제공하도록 노력하겠습니다.

모든 입력을 감사하십시오 :)

답변:


5

제공 한 링크에서 아래 줄을 봅니다.

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처음 2자를 자르기 때문에 대부분 오류 의 속성을 의심 합니다. 결과에 문자가 하나만 있으면 어떻게됩니까? 결과가 1.23456인 경우 위의 컷은 분명히 오류 의 원인이되는 1.값으로 나타납니다 .resultinteger expected

나머지 서버에서 제대로 작동하는 이유는 result변수에 단일 숫자 만있는 경우가 없기 때문 입니다. 결과가 단일 숫자 변수 인 경우 (위의 예에서 언급 한 것과 같은) 나머지 서버에서도 실패 할 가능성이 높습니다.


${result%%.*}소수점을 제거하는 올바른 확장입니다. 그러나 cut -c -2이로 인해 100 개 이상의 숫자로 인해 문제가 발생할 수 있으므로 완전히 삭제하는 것이 더 안전합니다.
Graeme

@Graeme, 나는 그것을 그리워했다. 나는 그 라인에서 다음과 같이 변경해야했다 :)
Ramesh

6

상황을 보면, bash가 숫자를 인식하지 못하도록 result변수 .뒤에 변수가 있습니다. 간단히 다음을 수행하여 오류를 재현 할 수 있습니다.

[ 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 범위의 결과에만 유효하기 때문에 사용하는 방법 은 그리 좋은 생각이 아닙니다. result0-9에서 (경우와 같이) 실패하며 99보다 큰 숫자도 실패합니다 .

업데이트 2

에서 아래 스테판의 코멘트 @ 임계 값과 비교했을 때, 당신은 라운드 아래에 더 낫다. 이를 고려할 때 문제의 스 니펫에 또 다른 작은 오류가 있습니다. 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
그러나 임계 값을 확인하기 위해 반올림 하고 싶지 않습니다 . 경고 임계 값이 50 인 경우 49.6은 여전히 정상result=$(( 100 * $used / $total )) 이어야합니다. 따라서 괜찮습니다.
Stéphane Chazelas

0

그래서 나는 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.