0

I am trying to monitor filesystem space using a shell script. That script should refer a config file that has alert status constraint. The config file is as below

FileSYSTEM  WARNING     CRITICAL
/dev/sda5   80  90
/dev/sda3   50  70
/dev/sda2   60  75
/dev/sda1   75  80
tmpfs       70  75

So whenever I run a script it should compare df -Ph's used percentage with that config file and trigger a warning(or) critical mail accordingly.

The script which I tried is as below

#!/bin/ksh
HOST=`hostname`
DATE=`date`
LOGDIR=/home/oracle/files/logs
CONFIG_FILE=/home/oracle/files/template

FILESYSTEM=`mount -l | egrep -v 'root'| awk '{print $3}'`

for i in $FILESYSTEM
do
df -Ph $i > ($LOGDIR)\FS.log
sed -e '/Filesystem/d' -e 's/\%/ /g' ${LOGDIR}/FS.log > ${LOGDIR}/FS1.log
SPACEUSED=$(awk '{print $5}' ${LOGDIR}/FS1.log)

while read -r line
do
FS_TEMPLATE=`awk {'print $1'}`
if ($i == $FS_TEMPLATE)
then
WARNING_LIMIT=`awk {'print $3'}`
CRITICAL_LIMIT=`awk {'print $2'}`
if ($SPACEUSED == $CRITICAL_LIMIT)
then
echo ' mail criticality'
elseif ($SPACEUSED -ge $WARNING_LIMIT)
then
echo 'waning'
fi
fi
done < $CONFIG_FILE
done


# Remove temporary work files.
rm -f ${LOGDIR}/FS.log
rm -f ${LOGDIR}/FS1.log

# End of Script

But it is not working. How could I achieve it?

1 Answer 1

2

The failures are that you try to select fields with e.g.

CRITICAL_LIMIT=`awk {'print $2'}`

without giving awk any input; you apparently wanted echo $line| or (in ksh bash zsh) <<<$line, and your if syntax is wrong: you need (( )) for arithmetic comparison, and something else entirely for string comparison, and elif instead of elseif. Other things are clumsier than necessary:

  • you initially exclude, only, any filesysem whose mount line includes root. I would want to monitor space usage on the root filesystem. However practically all systems today have several filesystems that aren't stored and thus have no space usage to be monitored: /proc and /sys usually, /dev or part of it often, sometimes others. If you run df without specifying a filesystem, it will do all meaningful filesystems for you. Even better, you only care about the filesystems that are in the config file, so just do those.

  • you read each line and (try to) split it clumsily with awk when read can do this for free

  • you (try to) test only if the usage is equal to a threshold; if e.g. '/dev/sda5' goes rapidly from 79% to 81% your logic won't give a warning for 80%. Usually people want alerts when usage is at or above a threshold.

  • the { and } in an awk script should go inside quotes, because braces are special characters to the shell (at least most shells) and may produce unintended and undesired results, although not in your specific cases

And you haven't tried to actually mail anything at all, but that's often system and environment dependent, so I'll leave that to you.

Applying all of those I would do:

#!/bin/ksh
CONFIG_FILE=/home/oracle/files/template
<$CONFIG_FILE while read filesys warn crit; do
  used=$( df -Ph "$filesys" | awk 'NR>1 {sub(/%/,"",$5);print $5}' )
  if (($used >= $crit)); then echo critical $used% on $filesys
  elif (($used >= $warn)); then echo warning $used% on $filesys; fi
done 

Alternatively you could leave the % in field 5 and used, and do the comparisons on the trimmed value ${used%\%} ; that's six versus half a dozen.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.