The following shell scrip will check the disk space and change the variable diskfull
to 1
if the usage is more than 10%
The last echo always shows
@OP, use an outer brace or ()
count=0
max=10
diskfull=0
df -HP | { while read disk b c d used e
do
if [ "$count" -gt 1 ];then
used=${used%?}
if [ "$used" -gt "$max" ];then
echo "overload: $disk, used: $used%"
diskfull=1
fi
fi
count=$(( count+1 ))
done
echo "diskfull: $diskfull"
}
This is a side-effect of using while
in a pipeline. There are two workarounds:
1) put the while
loop and all the variables it uses in a separate scope as demonstrated by levislevis86
some | complicated | pipeline | {
while read line; do
foo=$( some calculation )
done
do_something_with $foo
}
# $foo not available here
2) if your shell allows it, use process substitution and you can redirect the output of your pipeline to the input of the while loop
while read line; do
foo=$( some calculation )}
done < <(some | complicated | pipeline)
do_something_with $foo
you can do it this way with gawk(no need to use grep). for alerts you can send email to root.
threshold=10
df -HP | awk -v t="$threshold" -v msg="" 'NR>1 && $5+0 > t{
msg=msg $1" is "$5"\n"
}END{print msg}' | mail root
or check whether there is "msg" or not first
threshold=10
result=$(df -HP | awk -v t="$threshold" -v msg="" 'NR>1 && $5+0 > t{
msg=msg $1" is "$5"\n"
}END{print msg}')
if [ -n "$result" ];then
echo "Overload"
echo "$result" | mail root
fi
I think you must not be getting to the diskfull=1
line, because if you were, you would get no output at all-- the following exit
line would exit the script.
I don't know why this isn't working, but note that awk can handle the rest of the work:
diskfull=$(df -HP | grep -vE '^Filesystem|tmpfs|cdrom' | awk 'BEGIN { x = 0 } { if ($5 + 0 >= '$ALERT') { x = 1 } } END { print x }')
This way you don't need the while loop.
When using pipes the shell seams to use sub-shells to do the work. As $diskfull
is not known to these sub-shells the value is never changed.
See: http://www.nucleardonkey.net/blog/2007/08/variable_scope_in_bash.html
I modified your script as follows. It works for me and should work on your system too.
#!/bin/sh
diskfull=0
ALERT=10
stats=`df -HP | grep -vE '^Filesystem|tmpfs|cdrom|none|udev' | awk '{ print $5 "_" $1 }'`
for output in $stats
do
usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
partition=$(echo $output | sed s/.*_// )
#echo $partition - $usep
if [ $usep -le $ALERT ]; then
diskfull=1
break
fi
done
echo $diskfull
In this line:
usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
it's not necessary to use cut
. You can do this:
usep=$(echo $output | awk -F% '{ print $1}' )