Alerta para el rápido crecimiento del disco -- bash campo con file-system camp codereview Relacionados El problema

Alerting for rapid disk growth


5
vote

problema

Español

Tengo un servidor que es bastante estable (capacidad de disco) hasta que ocurra un cierto evento y luego la unidad crece a lo largo de dos días hasta que esté llena. Escribí un guión de bash muy simple, pero no estoy demasiado feliz con las partes de ella. Primero, quiero poder ver la capacidad como un porcentaje hasta la décima lugar. Además, hacer una evaluación tuve que eliminar mi valor de cualquier lugar decimal para compararlo contra mi umbral definido. Por último, siento que hice demasiado uso de cut donde podría haber sido más eficiente. Me encantaría conseguir algunos consejos para mejorar.

  #! /bin/bash  monDrive=/opt prevReading=/root/diskcheckreading.txt percentThreshold=1 emailAlert=alerts@domain.com  #Check if log file exists  if [ ! -f $prevReading ]     then         touch $prevReading         prev=$(printf "%0.2f " $(bc -l <<< $(df /opt | grep opt | cut -d' ' -f24)/$(df /opt | grep opt | cut -d' ' -f23)*100))         echo $prev > $prevReading  fi   #Get current percentage used of monitored drive current=$(printf "%0.2f " $(bc -l <<< $(df /opt | grep opt | cut -d' ' -f24)/$(df /opt | grep opt | cut -d' ' -f23)*100))  #import previous reading prev=$(cat $prevReading)  #Calculate the difference results=$(bc -l <<< $current-$prev )  #Convert to percentage results100=$(bc <<< $results*100)  #Remove any number after decimal place so that bash can evaluate rescleanup=$(echo $results100 | cut -d'.' -f1)  #Convert to percentage percentThreshold100=$(bc -l <<< $percentThreshold*100)  #Check if the difference exceeds the threshold if  [ $rescleanup -gt $percentThreshold100 ]      then printf ""$monDrive" has grown $results%% in the past hour.  $(hostname):$(pwd)/$(basename $0)" | mail -s "Disk Alert - $(hostname):$monDrive" $emailAlert  fi  #log current reading for next check emailecho $current > $prevReading   
Original en ingles

I have a server that is pretty stable (disk capacity) until a certain event occurs and then the drive grows over the course of two days until it is full. I wrote a very simple bash script but I'm not too happy with parts of it. First, I want to be able to see the capacity as a percent down to the tenths place. Also, doing an evaluation I had to strip my value of any decimal places to compare it against my defined threshold. Lastly I feel that I made too much use of cut where I could've been more efficient. I'd love to get some tips for improvement.

#! /bin/bash  monDrive=/opt prevReading=/root/diskcheckreading.txt percentThreshold=1 emailAlert=alerts@domain.com  #Check if log file exists  if [ ! -f $prevReading ]     then         touch $prevReading         prev=$(printf "%0.2f\n" $(bc -l <<< $(df /opt | grep opt | cut -d' ' -f24)/$(df /opt | grep opt | cut -d' ' -f23)*100))         echo $prev > $prevReading  fi   #Get current percentage used of monitored drive current=$(printf "%0.2f\n" $(bc -l <<< $(df /opt | grep opt | cut -d' ' -f24)/$(df /opt | grep opt | cut -d' ' -f23)*100))  #import previous reading prev=$(cat $prevReading)  #Calculate the difference results=$(bc -l <<< $current-$prev )  #Convert to percentage results100=$(bc <<< $results*100)  #Remove any number after decimal place so that bash can evaluate rescleanup=$(echo $results100 | cut -d'.' -f1)  #Convert to percentage percentThreshold100=$(bc -l <<< $percentThreshold*100)  #Check if the difference exceeds the threshold if  [ $rescleanup -gt $percentThreshold100 ]      then printf "\"$monDrive\" has grown $results%% in the past hour.\n\n$(hostname):$(pwd)/$(basename $0)" | mail -s "Disk Alert - $(hostname):$monDrive" $emailAlert  fi  #log current reading for next check emailecho $current > $prevReading 
     

Lista de respuestas

2
 
vote
  1. ¡Procede cuando prevReading El archivo no existe?

    Su script procede para crear el archivo primero, y luego casi realiza inmediatamente el mismo cálculo. En este caso, podría ser mejor simplemente crear el archivo primero, 9988776655544331 desde el script y luego espere a que su próxima invocación haga la comparación.

  2. realizando el mismo cálculo dos veces

    Está repitiendo los mismos comandos para configurar prev y current , por lo que debe ponerlo en una función:

      checkDiskUse() {     df "$monDrive" | awk '/'"$monDrive"'/{printf "%0.2f",$3/$2*100; exit}' }   
  3. cut -d' ' -f23/24 puede ser sustituido con awk

    Como se ilustra anteriormente, awk puede 'resolver' su uso extraño de cut - Llamar bc en ellos. Su uso de exit0 asume que la línea correspondiente tiene sus valores deseados (usados ​​/ Total) exactamente 99887776655443311 espacios en blanco delante de ellos, lo que puede estar equivocado en el futuro. DEJEMOS exit2 Haz el espacio para usted para usted, y simplemente extraer los valores del tercer y segundo, respectivamente ( 99887776655443313 , 99887766555443314 ).

  4. Validar contenidos de archivos

    Es una buena práctica para la cordura, verifique que el archivo de la que está leyendo tiene datos válidos. Una forma sencilla de hacerlo es verificar si 99887766555443315 es capaz de analizarlo correctamente o no:

      exit6  

    Si el valor de entrada exit7 es válido, 99887766555443318 devuelve con un código de salida exitoso. De lo contrario, la declaración procede a la pieza 'o' exit9 prev020 El script como una medida a prueba de fallas.

  5. prev1 vs prev2

    Como ha descubierto, el comando de prueba básico prev3 no se ocupa de los valores decimales, sino 99887776655443324 's incorporado prev5 expresión condicional sucede que manejan eso bien. Comparar:

      prev6  

para resumirlo

  prev7  

Nota: prev8 Contiene solo prev9 Al inicio, dado que solo la primera se escapa en la instrucción 99887766655443330 . Consulte los comentarios de una solución de sintaxis en 998877766554433331 (YMMV). Alternativamente, creo que el uso de current2 en lugar de la regex podría funcionar también:

  current3  
 
  1. Proceed when prevReading file does not exist?

    Your script proceeds to create the file first, and then almost immediately performs the same calculation. In this case, it might be better to just create the file first, exit from the script and then wait for its next invocation to do the comparison.

  2. Performing the same calculation twice

    You are repeating the same commands for setting prev and current, so you should put it in a function:

    checkDiskUse() {     df "$monDrive" | awk '/\'"$monDrive"'/{printf "%0.2f",$3/$2*100; exit}' } 
  3. cut -d' ' -f23/24 can be substituted with awk

    As illustrated above, awk can 'solve' your weird usage of cut-ting on whitespaces, and then calling bc on them. Your use of cut assumes that the relevant line has your desired values (used / total) exactly 23 whitespaces before them, which may be wrong in the future. Let awk do the whitespace parsing for you instead, and simply extract the third and second values respectively ($3, $2).

  4. Validate file contents

    It's good practice to sanity check that the file you are reading from has valid data. A simple way to do so is to check if printf is able to parse it correctly or not:

    printf "%0.2f" "$prev" > /dev/null || exit 

    If the input value $prev is valid, printf returns with a successful exit code. Otherwise, the statement proceeds to the 'or' || part and exit the script as a fail-safe measure.

  5. [ vs [[

    As you have discovered, the basic test command [ does not deal with decimal values, but bash's built-in [[ conditional expression happens to handle that well. Compare:

    $ [ 0.601 -gt 0.6 ] && echo Y bash: [: 0.601: integer expression expected $ [[ 0.601 > 0.6 ]] && echo Y Y 

To sum it up

monDrive=/opt prevReading=/root/diskcheckreading.txt percentThreshold=1 emailAlert=alerts@domain.com checkDiskUse() {     df "$monDrive" | awk '/\'"$monDrive"'/{printf "%0.2f",$3/$2*100; exit}' } [ -f $prevReading ] && prev=$(cat $prevReading) || { checkDiskUse > $prevReading; exit; } printf "%0.2f" "$prev" > /dev/null || exit current=$(checkDiskUse) results=$(bc <<< "$current - $prev") if [[ $results > $percentThreshold ]]     then printf "\"$monDrive\" has grown $results%% in the past hour.\n\n$(hostname):$(pwd)/$(basename $0)" | \         mail -s "Disk Alert - $(hostname):$monDrive" $emailAlert fi emailecho $current > $prevReading 

Note: $monDrive is assumed to only contain / at the start, since only the first is escaped in the awk statement. Refer to comments for a somewhat hack-y workaround in vim's syntax highlighting (YMMV). Alternatively, I think using END instead of the regex might work too:

df "$monDrive" | awk 'END{printf "%0.2f",$3/$2*100; exit}' 
 
 
         
         
1
 
vote
  • current4 es una exageración. Para cálculos simples use la expansión aritmética, por ejemplo.

      current5  
  • current6 incorporado es mucho más amigable que current7 / 998877766554433388 Combo:

      current9  
 
  • bc is an overkill. For simple calculations use arithmetic expansion, e.g.

    results = $(($current - $prev)) 
  • read built-in is way more friendly than grep/cut combo:

    df /opt | (read; read fs blocks used available rest; compute_percentage $used $available) 
 
 
   
   
0
 
vote
vote
La mejor respuesta
 

Según la ayuda recibida aquí, esta es la versión actualizada que se prueba y funciona. Gracias por la ayuda!

  checkDiskUse() {     df "$monDrive" | awk '/'"$monDrive"'/{printf "%0.2f",$3/$2*100; exit}' } 0  
 

Based on the help received here, this is the updated version that is tested and working. Thanks for the help!

#!/bin/bash   monDrive=/opt prevReading=/root/diskcheckreading.txt percentThreshold=1 emailAlert=alerts@domain.com  checkDiskUse() {         df "$monDrive" | awk 'END{printf "%0.2f",$2/$1*100; exit}' }  #Check if file exists with previous reading [ -f $prevReading ] && prev=$(cat $prevReading) || { checkDiskUse > $prevReading; exit; }  #Validate file content printf "%0.2f" "$prev" > /dev/null || exit  #Get current percentage used of monitored drive current=$(checkDiskUse)  #Calculate the difference results=$(bc -l <<< $current-$prev )  #Check if the difference exceeds the threshold if  [[ $results > $percentThreshold ]]      then printf "\"$monDrive\" has grown $results%% in the past hour.\n\n$(hostname):$(pwd)/$(basename $0)" | mail -s "Disk Alert - $(hostname):$monDrive" $emailAlert  fi  #log current reading for next check echo $current > $prevReading 
 
 

Relacionados problema

2  Fusionar directorios y mantener archivos que tengan más líneas  ( Merging directories and keep files that have more lines ) 
gol Mi objetivo es combinar directorios. Cada vez que un archivo tiene el mismo nombre en dos o más directorios, solo se debe mantener el número más alto ...

6  Compara el último tiempo de modificación con tiempo especificado  ( Compare last modification time with specfied time ) 
Estoy escribiendo una función en Python que compara el tiempo de modificación de un archivo en Linux (usando OS.STAT) con un tiempo específico y compare las f...

8  Extractor simple para Archivos de Pak de Quake-2  ( Simple extractor for quake 2 pak archives ) 
Estaba jugando con el código fuente de Quake-2 hoy y en algún punto desea extraer archivos de El .pak Archivos utilizados por el juego. Dado que no pude e...

1  Foldify - Una herramienta de carpeta de Python Tree Tree  ( Foldify a python folder tree manager tool ) 
El objetivo era crear una herramienta para ayudar a administrar las estructuras de las carpetas y permitirme crear plantillas de estas carpetas y almacenarlas...

5  Colector de archivos M3U  ( M3u file collector ) 
Soy nuevo en Python y escribió este código para recopilar todos los archivos en un archivo M3U (Lista de reproducción) y copiándolos en un directorio. impo...

5  Selector y reproductor de MP3 aleatorio  ( Random mp3 selector and player ) 
Entonces, soy un glotón para el castigo, o no tengo vida, pero yo escribió un script para responder una pregunta sobre Preguntar en preguntar Ubuntu como sol...

5  Mejorar este navegador de archivos de imagen (eliminar la redundancia)?  ( Improve this image file browser remove redundancy ) 
Déjame comenzar diciendo que el código funciona como es, pero creo que tiene mucha redundancia. Está escrito de esta manera, ya que seguí recibiendo nullpoint...

4  ¿Hay una manera 'mejor' de encontrar archivos de una lista en un árbol de directorios  ( Is there a better way to find files from a list in a directory tree ) 
He creado una lista de archivos usando find , 9988776655544336 . El comando Buscar es simplemente find . -type f -name "<search_pattern>" > foundlist.lst...

2  Clase PHP para el manejo de archivos y la creación  ( Php class for file handling and creation ) 
Esta es una clase muy simple para manejar archivos. Permite acceder, crear y modificar archivos en el sistema o 2 archivos falsos (uno en la memoria y otros...

2  Estantería con clasificación, categorías y archivo E / S  ( Bookshelf with sorting categories and file i o ) 
He estado trabajando en un proyecto originalmente para la escuela con respecto al diseño orientado a objetos, donde se suponía que debía escribir una clase pa...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos