เชลล์สคริปต์เพื่อส่งเมลแจ้งเตือนหากการใช้งานดิสก์เกิน 90%


11

ฉันต้องการติดตั้งสคริปต์บนเซิร์ฟเวอร์ของฉันซึ่งจะส่งการแจ้งเตือนทางอีเมลโดยอัตโนมัติหากการใช้งานดิสก์เกิน 90% และการแจ้งเตือนทางอีเมลครั้งที่สองเมื่อเกินกว่า 95% ระบบแฟ้มของฉันคือและติดประเด็นก็คือabc:/xyz/abc/pqr

ฉันได้ลองสิ่งนี้แล้ว:

ADMIN="someone@def.com" 
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 

คำตอบ:


14

ข้อผิดพลาดเกิดจากหนึ่งในข้อโต้แย้งที่-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 

6

หากคุณเปลี่ยนพิมพ์เป็น printf โดยใช้% d เปอร์เซ็นต์จะกลายเป็นจำนวนเต็ม ลอง:

printf("%d", $5);

ซึ่งจะแปลง 91% เป็น 91 ดังนั้นคำสั่งสุดท้ายคือ:

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

คำสั่งข้างต้นเป็นภาษาอังกฤษ: "รับการใช้พื้นที่ดิสก์ในรูปแบบที่มนุษย์สามารถอ่านได้กรองด้วย grep ไปยังดิสก์ที่เราต้องการดูไปป์ที่บรรทัดนั้น awk และพิมพ์คำที่ 5 คั่นด้วยช่องว่าง (ลบออกหมด) และรูปแบบ สตริงผลลัพธ์เป็นจำนวนเต็มสำหรับฉันคำสั่งคืนค่าจำนวนเต็ม78ซึ่งหมายความว่าดิสก์เต็ม 78%


3
$ df | tail +2 | sed s/%//g | awk '{ if($5 > 90) print "Alert "$0;}'
  • df | tail +2 รับเอาต์พุตทั้งหมดหลังจากข้าม 2 บรรทัดแรก
  • sed s/%//g แถบเปอร์เซ็นต์สัญญาณ
  • awk ... พิมพ์ "Alert ... " ถ้าฟิลด์ที่ 5 ในเอาต์พุตมีจำนวนมากกว่า 90

1
ยินดีต้อนรับสู่ Stack Exchange! เรากำลังมองหาคำตอบยาว ๆ ที่ให้คำอธิบายและบริบท อย่าเพียงแค่ให้คำตอบเดียว อธิบายวิธีการใช้งาน คำตอบที่ไม่รวมคำอธิบายอาจถูกลบออก
G-Man กล่าวว่า 'Reinstate Monica'

0

นี่คือตัวแปรของฉัน:

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

0

ฉันไม่สามารถแสดงความคิดเห็นในคำตอบของ Gilles ข้างต้น แต่เพิ่งทราบว่า awk กำลังทำการเปรียบเทียบแบบอิงสตริงในส่วนที่สองโดยที่:

$5 >= ALERT

ฉันสังเกตเห็นสิ่งนี้เมื่อฉันกำลังทดสอบเกณฑ์ตัวเลขหลักเดียว คุณสามารถบังคับให้ร่ายเป็น int โดยใช้ +0 ดังนั้นการเปรียบเทียบจะกลายเป็น:

$5+0 >= ALERT
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.