Filesystem alert shell script not working!!

Hi All,

My below shell script is not capturing %used value in the filesystem alert in the subject of the mail alert:

Code:

#!/bin/bash

export DBALIST="abc@xyz.com"

df -k /oradata/xyz/archive > dfk.result
archive_capacity=`awk -F" " '{ print $5 }' dfk.result|grep -i %| cut -c 1-4`
if [[ $archive_capacity > 60% ]]
then
mailx -s "Filesystem /oradata is ${archive_capacity} filled" $DBALIST < dfk.result
fi

First, i do not understand what you need the temporary file for and you SHOULD AVOID backticks:

df -k /oradata/xyz/archive > dfk.result
archive_capacity=`awk -F" " '{ print $5 }' dfk.result|grep -i %| cut -c 1-4`

could be replaced by

archive_capacity=$(df -k /oradata/xyz/archive|awk -F" " '{ print $5 }' |grep -i %| cut -c 1-4)

But, honestly, whenever i see a awk|grep|cut i know there is something deeply amiss. All that grepping and cutting can be done inside awk, but i do not now what your exact df-output is, so it is hard to suggest what the awk-line should exactly look like.

Furthermore, this:

if [[ $archive_capacity > 60% ]]

cannot work: the ">" operator of the test -utility is not understood by all versions of test but even the ones that do only compare integers and "60%" is not an integer - it is a string. You should get rid of the "%" sign when you create the $archive_capacity content and then do like:

if [[ $archive_capacity -gt 60 ]]

first, this is an integer operation and second "-gt" (greater than) is an operator every test will understand.

I hope this helps.

bakunin

@bakunin, the [[ ]] compound is not the test command. (But the [ command (that needs ] as its last argument) is test .)
If the shell understands the [[ ]] then it should also understand its > operator: a string comparison.
And here is the problem: [[ 70% > 60% ]] is true but [[ 100% > 60% ]] is false.
While the -gt operator does a number comparison.

A quick-and-dirty trick is to foster a cast to a number:

df -kP /oradata/xyz/archive | awk 'NR>1 { print $5+0 }'

or

df -kP /oradata/xyz/archive | awk 'NR>1 { print int($5) }'

or

df -kP /oradata/xyz/archive | awk 'NR>1 { printf "%d\n", $5 }'

But it might not work with all awk versions.
Very safe is

df -kP /oradata/xyz/archive | awk 'NR>1 { gsub(/%/,""); print $5 }'

You need to also remove the header line, as shown by MadeInGermany. How about

cap=( $(df /oradata/xyz/archive | tee dfk.result | tail -n+2) )
if [ ${cap[4]%\%} -gt 60 ]
  then mail ... dfk.result
  fi

This is right and i am well aware of the difference between [[...]] (built-in) and [...] ( /bin/test ). Still, the built-in was made to work like (or, at the very least, "similar to") the original test-command and in this specific case there should be no difference. I should have made that thought process clearer, though.

Exactly. Which is why i suggested to get rid of the percent-symbol so that the shell deals with integers instead of strings.

I hope this helps.

bakunin

Could I chip in that I prefer to add the -P flag to df in case there are long device or filesystem names that cause the output to split the output on to separate lines.

Just a thought,
Robin

Good point; the -P works around a long-term bug in GNU df.
Meanwhile, in recent distros, it should have been fixed.