2013-04-20 11 views
6

Kabuk için nispeten yeni ve Shell'deki dizileri kullanmaya çalışıyorum ve iyi çalışmıyor. OpenVZ kapsayıcılarını belirli bir bant genişliği eşiğine belirli bir süre çarptığında askıya almak için bir komut dosyası yazmaya çalışıyorum.Bozuk dizi alt yordamı

Benim komut dosyası:

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

Ve hatalar:

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

Ben dizi simge birkaç varyasyonu denedim ama bu hataların kurtulmak için görünmüyor olabilir. Yani çizgi 38

+0

Her yerde bir kaç tane "$' eksiksiniz. Örneğin. Örneğin, zamanlar [$ i] 'olmalıdır. – Mat

+0

Özür dileriz, yazıyı değiştirdim. Aynı hatalar olsa da. – James

+0

@Mat aslında bir dizi alt dizininin içinde $ $ işareti gerekli değildir. – kojiro

cevap

9

,

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

kez yineleme sırasında times[-1] bakın olur. Negatif endeksler only very recently part of bash arrays şeklindedir, bu nedenle büyük ihtimalle bu hatayı almanız olasıdır.

Benzer şekilde, 54 ve 67 numaralı satırlarda bir kez negatif dizin alt kümesine ulaşırsınız. [0 - 1]'dan kaçınmak için döngülerinizi ayarlayın.