디스크 사용량이 90%를 초과하면 경고 이메일을 보내는 쉘 스크립트

디스크 사용량이 90%를 초과하면 경고 이메일을 보내는 쉘 스크립트

디스크 사용량이 90%를 초과하면 자동으로 이메일 경고를 보내고 디스크 사용량이 95%를 초과하면 두 번째 이메일 경고를 보내는 스크립트를 내 서버에 구현하고 싶습니다. 내 파일 시스템은 abc:/xyz/abc이고 마운트 지점은 입니다 /pqr.

나는 이것을 시도했습니다 :

ADMIN="[email protected]" 
ALERT=90 
df -H | grep -vE 'abc:/xyz/pqr | tmpfs |cdrom' | awk '{ print $5 " " $1 }' | while read output; do 
  usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 ) 
  partition=$(echo $output | awk '{ print $2 }' ) 
    if [ $usep -ge $ALERT ]; then 
      mail -s "Alert: Almost out of disk space $usep" $ADMIN 
    fi 
  done

하지만 다음과 같은 오류가 발생합니다.

line 7: [: Use: integer expression expected 

답변1

이 오류는 -ge매개변수 중 하나가 숫자가 아니기 때문에 발생합니다. $ALERT항상 숫자이기 때문에 $usep범인임에 틀림없습니다. 출력이 구문 분석되는 방식에 몇 가지 문제가 있어 출력이 숫자가 아닙니다 dh.$usep

파일 시스템의 길이에 따라 dh출력이 여러 줄로 분할될 수 있습니다. 일부 행은 필터에 의해 포착되어 의미 없는 데이터를 생성합니다. 이 동작을 방지하고 에서 구문 분석 가능한 출력을 얻으려면 dh-P옵션을 전달하십시오.

또한 df헤더 행을 인쇄하는데, 이로 인해 다시 의미 없는 데이터가 생성됩니다.

필터가 상당히 복잡합니다. awk를 한 번 사용해 보겠습니다. 그 문제에 대해서는 awk 내에서 백분율을 필터링할 수 있습니다(그러나 아래 스크립트에서는 그렇게 하지 않았습니다).

df -H | awk '
    NR == 1 {next}
    $1 == "abc:/xyz/pqr" {next}
    $1 == "tmpfs" {next}
    $1 == "/dev/cdrom" {next}
    1 {sub(/%/,"",$5); print $1, $5}
' | while read filesystem percentage; do
    if [ "$percentage" -ge "$ALERT" ]; then 
      mail -s "Alert: Almost out of disk space ($usep%) on $filesystem" "$ADMIN"
    fi 
  done

NR==1첫 번째 줄과 일치하므로 NR==1 {next}첫 번째 줄을 건너뜁니다. 다음 몇 줄에서는 일부 파일 시스템을 제외합니다(설명에는 관심이 있다고 표시되어 있지만 abc:/xyz/pqr코드에서는 제외됩니다). 인쇄하기 전에 마지막 awk 행이 %백분율 열에서 제거됩니다.

모든 파일 시스템에 대한 메일을 보내는 것이 좋습니다. 이번에는 awk에서 모든 분석을 수행했습니다.

message=$(df -h | awk -v ALERT="$ALERT" '
    NR == 1 {next}
    $1 == "abc:/xyz/pqr" {next}
    $1 == "tmpfs" {next}
    $1 == "/dev/cdrom" {next}
    1 {sub(/%/,"",$5)}
    $5 >= ALERT {printf "%s is almost full: %d%%\n", $1, $5}
')
if [ -n "$message" ]; then
  echo "$message" | mail -s "Alert: Almost out of disk space" "$ADMIN"
fi 

답변2

%d를 사용하여 print를 printf로 변경하면 백분율은 정수가 됩니다. 노력하다:

printf("%d", $5);

이는 91%를 91로 변환합니다. 따라서 최종 명령은 다음과 같습니다.

df -H | grep /dev/xvde1 | awk '{ printf "%d", $5}'

위 명령의 영어는 다음과 같습니다. "사람이 읽을 수 있는 형식으로 디스크 공간 사용량을 가져옵니다. grep을 사용하여 보고 싶은 디스크를 필터링합니다. 행을 awk로 파이프하고 공백으로 구분된 5번째 단어(null 값 제거됨)를 인쇄하고 결과 문자열이 형식화됩니다. 제 경우에는 이 명령이 정수를 반환합니다. 78이는 디스크가 78% 찼음을 의미합니다.

답변3

$ df | tail +2 | sed s/%//g | awk '{ if($5 > 90) print "Alert "$0;}'
  • df | tail +2처음 두 줄을 건너뛴 후 모든 출력 가져오기
  • sed s/%//g백분율 기호 제거
  • awk ...출력의 5번째 필드가 90보다 큰 숫자이면 "Alert..."를 인쇄합니다.

답변4

위의 Gilles의 답변에 대해서는 언급할 수 없지만 awk는 두 번째 부분에서 문자열 기반 비교를 수행합니다.

$5 >= ALERT

한 자릿수 임계값을 테스트할 때 이 사실을 발견했습니다. +0을 사용하여 int로 변환할 수 있으므로 비교는 다음과 같습니다.

$5+0 >= ALERT

관련 정보