Script de Shell para enviar un correo de alerta si el uso del disco supera el 90%

11

Quiero implementar un script en mi servidor que enviará automáticamente alertas por correo electrónico si el uso del disco supera el 90% y la segunda alerta por correo electrónico cuando supere el 95%. Mi sistema de archivos es abc:/xyz/abcy el punto de montaje es /pqr.

He intentado esto:

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

Pero recibo un error que dice

line 7: [: Use: integer expression expected 
Rui F Ribeiro
fuente

Respuestas:

13

El error se debe a que uno de los argumentos -geno es numérico. Como $ALERTsiempre es numérico, $useptiene que ser el culpable. Hay varios problemas con la forma en que analiza la salida dhque resultan en $usepno ser numéricos.

Dependiendo de la longitud de los sistemas de archivos, dhpuede dividir su salida en varias líneas. Las líneas parciales quedarán atrapadas en su filtro y generarán datos sin sentido. Para evitar este comportamiento y obtener un resultado analizable dh, pase la -Popción.

También dfimprime una línea de encabezado que nuevamente generará datos sin sentido.

Tu filtro es bastante complejo. Usaría un solo pase de awk. Para el caso, podría filtrar el porcentaje dentro de awk (pero no lo he hecho en el siguiente script).

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==1coincide con la primera línea, por lo que NR==1 {next}omite la primera línea. Las siguientes líneas excluyen algunos sistemas de archivos (tenga en cuenta que su descripción dice que le interesa abc:/xyz/pqr, pero su código lo excluye). La última línea awk elimina el %de la columna de porcentaje antes de imprimirlo.

Sería mejor enviar un solo correo sobre todos los sistemas de archivos. Esta vez estoy haciendo todo el análisis en 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- deja de ser malvado'
fuente
6

Si cambia print a printf usando% d, el porcentaje se convertirá en un entero. Tratar:

printf("%d", $5);

que convertirá 91% a 91. Entonces el comando final es este:

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

El comando anterior en inglés: "Obtenga el uso del espacio en disco en formato legible para humanos. Filtre con grep al disco que queremos ver. Canalice esa línea a awk e imprima la quinta palabra delimitada por espacio (se eliminan los vacíos) y formatee la cadena resultante como un entero. Para mí, el comando devuelve el entero, lo 78que significa que el disco está lleno al 78%.

SeanO
fuente
3
$ df | tail +2 | sed s/%//g | awk '{ if($5 > 90) print "Alert "$0;}'
  • df | tail +2 toma toda la salida después de omitir las primeras 2 líneas
  • sed s/%//g tiras de signos de porcentaje
  • awk ... imprime "Alert ..." si el quinto campo en la salida es un número mayor que 90
Ashis Lenka
fuente
1
¡Bienvenido a Stack Exchange! Estamos buscando respuestas largas que brinden alguna explicación y contexto. No solo dé una respuesta de una línea; explica cómo funciona Las respuestas que no incluyen explicaciones pueden eliminarse.
G-Man dice 'Reincorporar a Monica'
0

Aquí está mi variante:

#!/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
fuente
0

No puedo comentar la respuesta de Gilles anterior, pero solo tenga en cuenta que awk está haciendo una comparación basada en cadenas en la segunda parte, donde:

$5 >= ALERT

Me di cuenta de esto cuando estaba probando umbrales de un solo dígito. Puede forzar una conversión a int usando +0, por lo que la comparación se convierte en:

$5+0 >= ALERT
kmac
fuente