Skrypt powłoki, aby wysłać wiadomość alarmową, jeśli użycie dysku przekroczy 90%

11

Chcę zaimplementować skrypt na moim serwerze, który będzie automatycznie wysyłać powiadomienia e-mail, jeśli użycie dysku wzrośnie powyżej 90%, a drugie powiadomienie e-mail, gdy przekroczy 95%. Mój system plików jest, abc:/xyz/abca punktem podłączenia jest /pqr.

Próbowałem tego:

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

Ale pojawia się błąd, który mówi

line 7: [: Use: integer expression expected 
Rui F. Ribeiro
źródło

Odpowiedzi:

14

Błąd wynika z tego, że jeden z argumentów -genie jest liczbowy. Ponieważ $ALERTzawsze jest to liczba, $usepwinowajcą musi być. Istnieje kilka problemów ze sposobem analizowania danych wyjściowych, dhktóre powodują, $usepże nie są numeryczne.

W zależności od długości systemów plików dhmoże podzielić dane wyjściowe na kilka wierszy. Częściowe linie zostaną przechwycone w filtrze i spowodują nonsensowne dane. Aby uniknąć tego zachowania i uzyskać analizowalne dane wyjściowe dh, należy przekazać tę -Popcję.

Również dfdrukuje wiersz nagłówka, który ponownie spowoduje nonsensowny danych.

Twój filtr jest dość złożony. Użyłbym jednego przejścia awk. W tym przypadku możesz wykonać filtrowanie procentowe w awk (ale nie zrobiłem tego w poniższym skrypcie).

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==1dopasowuje pierwszą linię, więc NR==1 {next}pomija pierwszą linię. Następne kilka wierszy wyklucza niektóre systemy plików (zauważ, że twój opis mówi, że jesteś zainteresowany abc:/xyz/pqr, ale kod go wyklucza). Ostatni wiersz awk usuwa %kolumnę procentową przed wydrukowaniem.

Przyjemniej byłoby wysłać jedną wiadomość o wszystkich systemach plików. Tym razem wykonuję całą analizę w 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 
Gilles „SO- przestań być zły”
źródło
6

Jeśli zmienisz print na printf za pomocą% d, wartość procentowa stanie się liczbą całkowitą. Próbować:

printf("%d", $5);

który zamieni 91% na 91. Zatem ostateczne polecenie jest następujące:

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

Powyższe polecenie w języku angielskim: „Uzyskaj użycie miejsca na dysku w formacie czytelnym dla człowieka. Filtruj grep na dysk, na który chcemy patrzeć. Przeciągnij ten wiersz, aby awk i wydrukował piąte słowo rozdzielone spacją (usunięte puste) i sformatuj wynikowy ciąg jako liczba całkowita. Dla mnie polecenie zwraca liczbę całkowitą, 78co oznacza, że ​​dysk jest zapełniony w 78%.

SeanO
źródło
3
$ df | tail +2 | sed s/%//g | awk '{ if($5 > 90) print "Alert "$0;}'
  • df | tail +2 pobiera wszystkie dane wyjściowe po pominięciu pierwszych 2 wierszy
  • sed s/%//g usuwa znaki procentu
  • awk ... wypisuje „Alert ...”, jeśli piąte pole na wyjściu jest liczbą większą niż 90
Ashis Lenka
źródło
1
Witamy w Stack Exchange! Szukamy długich odpowiedzi, które zawierają wyjaśnienia i kontekst. Nie udzielaj odpowiedzi tylko w jednym wierszu; wyjaśnij, jak to działa. Odpowiedzi, które nie zawierają wyjaśnień, mogą zostać usunięte.
G-Man mówi „Przywróć Monikę”
0

oto mój wariant:

#!/bin/bash

ADMIN=yermail@yerdom.com
ALERT=90
df -H | grep -vE 'abc:/xyz/pqr | tmpfs |cdrom|Used' | awk '{ print $5 " " $1 }' | while read output; do 
usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 ) 
echo $usep
partition=$(echo $output | awk '{ print $2 }' ) 
if [ $usep -ge $ALERT ]; then 
  echo  "Alert: Almost out of disk space $usep" 
  df -H | mail -s "Alert: out of disk space $usep"  $ADMIN
fi 
done
fyg
źródło
0

Nie jestem w stanie skomentować powyższej odpowiedzi Gillesa, ale pamiętaj, że awk dokonuje porównania opartego na łańcuchach w drugiej części, gdzie:

$5 >= ALERT

Zauważyłem to, kiedy testowałem progi jednocyfrowe. Możesz wymusić rzutowanie na int za pomocą +0, więc porównanie wygląda następująco:

$5+0 >= ALERT
kmac
źródło