2013-04-20 38 views
6

Jestem względnie nowy dla Shell i próbuję używać tablic w Shell i nie działa dobrze. Próbuję napisać skrypt, aby zawiesić kontenery OpenVZ, jeśli osiągną pewien próg przepustowości w danym okresie.Niepoprawny indeks tablicy

Mój skrypt:

#!/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 

a błędy:

script.sh: line 38: times: bad array subscript 
script.sh: line 54: bytes: bad array subscript 
script.sh: line 67: bytes: bad array subscript 

Próbowałem kilka odmian indeks tablicy, ale ja nie potrafię pozbyć się tych błędów.

+0

Tęsknisz za kilkoma "$" w każdym miejscu. na przykład na przykład powinno być 'razy [$ i]'. – Mat

+0

Przepraszam, poprawiłem wpis. Same błędy. – James

+0

@Mat właściwie znak '$' nie jest wymagany wewnątrz indeksu tablicy. – kojiro

Odpowiedz

9

Więc na linii 38,

if ((times[$i] > times[$i - 1] + $SECS + 10)) 

odsyła do times[-1] raz podczas iteracji. Indeksy ujemne to only very recently part of bash arrays, dlatego najprawdopodobniej otrzymujesz błąd.

Podobnie z liniami 54 i 67 raz trafia się jeden negatywny indeks tablicowy. Dostosuj pętle, aby uniknąć [0 - 1].

Powiązane problemy