2013-04-20 4 views
6

私はシェルには比較的新しいので、シェルで配列を使用しようとしていますが、うまく機能しません。私はOpenVZコンテナを一時停止するためのスクリプトを書こうとしていますが、ある期間にわたって特定の帯域幅のしきい値に達すると、不良配列の添え字

マイスクリプト:

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

とエラー:

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

私は配列の添字のいくつかのバリエーションを試してみたが、私はこれらのエラーを取り除くように見えることはできません。だから、ライン38上の

+0

あなたはかなりの数の '$'を全部欠けています。例えば例えば ​​'times [$ i]'でなければなりません。 – Mat

+0

申し訳ありませんが、私は投稿を修正しました。しかし、同じエラー。 – James

+0

@Mat実際には '$'記号は配列の添字の中に必要ではありません。 – kojiro

答えて

9

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

は一回の反復中times[-1]を参照することになります。負のインデックスはonly very recently part of bash arraysです。そのため、エラーが発生する可能性が最も高くなります。

同様に、54行目と67行目では、負の配列添字を1回打っています。 [0 - 1]を避けるようにループを調整してください。

関連する問題