I'm relatively new to Shell and I've been trying to use arrays in Shell and it's not working well. I'm trying to write a script to suspend OpenVZ containers should they hit a certain bandwidth threshold over a period of time.
My script:
#!/bin/bash
#Thresholds are in bytes per second and count1 must > count2
LOGDIR="/var/log/outbound_ddos"
SECS=10
THRESHOLD1=65536000
COUNT1=10
THRESHOLD2=117964800
COUNT2=2
while [ 1 ]
do
for veid in $(/usr/sbin/vzlist -o veid -H)
do
# Create the log file if it doesn't already exist
if ! test -e $LOGDIR/$veid.log; then
touch $LOGDIR/$veid.log
fi
# Parse out the inbound/outbound traffic and assign them to the corresponding variables
eval $(/usr/sbin/vzctl exec $veid "grep venet0 /proc/net/dev" | \
awk -F: '{print $2}' | awk '{printf"CTOUT=%s\n", $9}')
# Print the output and a timestamp to a log file
echo $(date +%s) $CTOUT >> $LOGDIR/$veid.log
# Read last 10 entries into arrays
i=0
tail $LOGDIR/$veid.log | while read time byte
do
times[$i]=time; bytes[$i]=byte
let i++
done
# Sanity checks and calculations
for (( i=0; i<COUNT1; i++ ))
do
# Sanity check on the time
if (( times[$i] > times[$i - 1] + $SECS + 10 ))
then continue
fi
# Calculate differences
let "diff[$i] = bytes[$i+1] - bytes[$i]"
done
# Work out thresholds and suspend where necessary
# Higher threshold first
t2=0
for (( i=COUNT1-1; i>=0; i-- ))
do
if [ ! diff[$i] ]
then continue
else
if (( bytes[$i] < THRESHOLD1 * SECS + bytes[$i-1] + 1 ))
then continue
else let t2++
fi
fi
done
#Lower threshold last
t1=0
for (( i=COUNT1-1; i>=0; i-- ))
do
if [ ! diff[$i] ]
then continue
else
if (( bytes[$i] < THRESHOLD1 * SECS + bytes[$i-1] + 1 ))
then continue
else let t1++
fi
fi
done
# Suspend where necessary
if (( ($t2 >= $COUNT2) || ($t1 >= $COUNT1) ))
then vzctl stop veid
fi
done
sleep $SECS
done
And the errors:
script.sh: line 38: times: bad array subscript
script.sh: line 54: bytes: bad array subscript
script.sh: line 67: bytes: bad array subscript
I've tried several variations of the array subscript but I can't seem to get rid of those errors.
So on line 38,
if (( times[$i] > times[$i - 1] + $SECS + 10 ))
would refer to times[-1]
once during the iteration. Negative indices are only very recently part of bash arrays, so that is most likely why you are getting the error.
Likewise with lines 54 and 67 you're hitting a negative array subscript once. Adjust your loops to avoid [0 - 1]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With