Reputation: 85
I have this code, which basically does a loop inside the DF command to see which disks are more than 90% full.
df -H | sed 1d | awk '{ print $5 " " $1 }' | while read -r dfh;
do
#echo "$output"
op=$(echo "$dfh" | awk '{ print $1}' | cut -d'%' -f1 )
partition=$(echo "$dfh" | awk '{ print $2 }' )
if [ $op -ge 90 ];
then
echo ">> ### WARNING! Running out of space on \"$partition ($op%)\" on $(hostname) as on $(date)" >> LOGFILE
echo -e ">> ### WARNING! Running out of space on \"$partition ($op%)\" on $(hostname) as on $(date)"
echo ">> There is not enough left storage in the disk to perform the upgrade, exiting..." >> LOGFILE
echo -e ">> There is not enough left storage in the disk to perform the upgrade, exiting..."
exit 1
elif [ $op -ge 85 ];
then
echo -e ">> ### WARNING! Running out of space on \"$partition ($op%)\" on $(hostname) as on $(date)" >> LOGFILE
echo ">> ### WARNING! Running out of space on \"$partition ($op%)\" on $(hostname) as on $(date)"
echo ">> There enough left storage in the disk to perform the upgrade, but it is recommended to first increase the size of the disk $partition" >> LOGFILE
echo -e ">> There enough left storage in the disk to perform the upgrade, but it is recommended to first increase the size of the disk $partition"
fi
done
if [ "$?" -eq 1 ];
then
exit
else
echo -e ">> There is enough left storage in the disk to continue with the upgrade, OK"
fi
I want it to exit only if at least one disk is more than 90% full, that's the pourpose of the last if statement
The problem here is that the loop exits on the first disk recognised at more than 90%, this is bad because if I have 3 disks at more than 90% it will only report one of them (the first one in the loop) and then exit. Basically I want the script to report all the disks that are at 90% or more (and the ones that are at 85% too but without exiting, as you can read).
Is this possible? Thank you in advance
Upvotes: 0
Views: 144
Reputation: 212178
You could do something like:
#!/bin/sh
warn=${1-85}
fail=${2-90}
test "$warn" -lt "$fail" || { echo Invalid parameters >&2; exit 1; }
check_disk(){
op=${1%%%}
partition=${2}
if test "$op" -ge "$warn"; then
tee -a LOGFILE <<-EOF
>> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)
>> There is not enough left storage in the disk to perform the upgrade, exiting...
EOF
fi
if test "$op" -ge "$fail"; then
return 1
fi
} 2> /dev/null
rv=0
df -H | awk 'NR > 1{ print $5 " " $1 }' \
| { while read -r op partition; do
if ! check_disk "$op" "$partition"; then rv=1; fi
done
test "$rv" -eq 0
} || exit 1
A few notes:
You must have literal hard tabs as indentation if you want the <<-
to suppress the indentation in the output.
You need to put the while/done
in the brackets to give the rv
variable the full scope to be able to check it. If you just do df ... | while do/done
, then the variable will be unset outside of the pipeline.
This is still a bit kludgy, and it would probably be better to do the whole thing in awk
instead of having the while/do
loop in the shell at all, but these are some ideas. In particular, you definitely do not want to be writing the same echo
line 4 times!
Also note that parsing the output of df
is really fragile. On my box, there are lines in which the filesystem column contains whitespace, so that the 5th column is not the current usage of the mountpoint. This script will probably not work as desired on such output.
Upvotes: 2
Reputation: 189317
Your script looks like it's screaming loudly to be refactored into Awk. But here is a more gentle refactoring.
rc=0
df -H |
awk 'NR>1 { n=$5; sub(/%/, "", n); print n, $1 }' |
while read -r op partition;
do
if [ $op -ge 90 ];
then
tee -a LOGFILE <<-________EOF
>> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)
>> There is not enough left storage in the disk to perform the upgrade, exiting...
________EOF
rc=1
elif [ $op -ge 85 ];
then
tee -a LOGFILE <<-________EOF
>> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)
>> There enough left storage in the disk to perform the upgrade, but it is recommended to first increase the size of the disk $partition
________EOF
fi
[ "$rc" -eq 0 ]
done &&
echo ">> There is enough left storage in the disk to continue with the upgrade, OK" ||
exit 1
This keeps track of rc
while looping over all the partitions, then proceeds with the final condition only when the loop is done.
Generally, avoid echo -e
in favor of printf
, though here, since the -e
wasn't doing anything useful anyway, a here document worked better.
Upvotes: 2
Reputation: 7253
You can do it in one check, like this:
$ a=10 b=5 c=7 ; (( a>=10 && b>=10 && c>=10 )) && echo 'all >= 10'
$ a=10 b=5 c=10; (( a>=10 && b>=10 && c>=10 )) && echo 'all >= 10'
$ a=10 b=10 c=10; (( a>=10 && b>=10 && c>=10 )) && echo 'all >= 10'
all >= 10
Upvotes: 0