디스크 사용량이 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