Bash script помощ ако може

15 отговора 823 прегледа
#1

Bash script помощ ако може

Значи имам следното положение:
сървър 486DX4/120MhZ i 32MB RAM на който върви Slackware. Сървара се използва за рутиране на нет мужду 5-7 човека в мрежа от 20. Използва се Netastat+MySQL. Всичко е настроено и отчита както трябва. Проблема е че услугата е на трафик и трябва по някакъв начин да спирам потребителите при достигане на лимита. Рових се доста време не можах да открия добро решение (в смисъл което на мен да ми харесва и да ми върши работа) и за това реших да седна да си напиша един скрипт да спира юзерите. Седнах и написах един скрипт, но (както винаги има едно голамо НО) нещо явно не мога да се оправя с масива, който предлага BASH.

Ето това е скрипта:


#!/bin/bash

basepath='/home/test/ip/'
script_path='/home/test/scripts/'

# Read users

FILENAME=/home/test/iptraff
temporary_file=/home/test/temporary
declare -a array1
declare -a IP
declare -a max_traff
declare -a temp_ip
declare -a temp_traf
declare -a temp
declare -a traf_array

array1=( `cat "$FILENAME"`)
count=${#array1[*]}
i=0
ii=0

while [ $i -lt $count ]; do
IP=( "${IP[@]}" "${array1}" )
max_traff=( "${max_traff[@]}" "${array1[i+1]}")
let i=i+2
let ii=ii+1
done

i1=0
count_users=${#IP[*]}

DATA=`date`
mesec_word=${DATA: 4: 3}
godina=${DATA: -4}

case $mesec_word in
"Jan" | "яну" ) mesec=01;;
"Feb" | "фев" ) mesec=02;;
"Mar" | "мар" ) mesec=03;;
"Apr" | "апр" ) mesec=04;;
"May" | "май" ) mesec=05;;
"Jun" | "юни" ) mesec=06;;
"Jul" | "юли" ) mesec=07;;
"Aug" | "авг" ) mesec=08;;
"Sep" | "сеп" ) mesec=09;;
"Oct" | "окт" ) mesec=10;;
"Nov" | "ное" ) mesec=11;;
"Dec" | "дек" ) mesec=12;;
esac

# Read database

i=0
while [ $i -lt $count_users ]; do
string_for_mysql="select input from traffic where ip='"${IP}"' and time>='"$godina"-"$mesec"-01' and time<='"$godina"-"$mesec"-31'"

/usr/local/mysql/bin/mysql -u root --password=parola --database=netacct --execute="$string_for_mysql" > $basepath${IP}
let i=i+1
done

users=0
while [ $users -lt $count_users ]; do
traf_array=( `cat "$basepath""${IP[users]}"`)
cnt_traf=${#traf_array[*]}
i=1
tmp_traf=0
while [ $i -lt $cnt_traf ]; do
tmp_traf=$[tmp_traf]+$[traf_array[i+1]]
let i=i+1
done

curr_traf=$[tmp_traf/1024/1024]

if [ $[curr_traf] -gt $[max_traff[users]] ]
then
$script_path${IP[user]}
fi

let users=users+1

done


Променливата FILENAME представлява файл от вида
192.168.0.50 1200
192.168.0.32 800


като първата част е IP-то а втората е максималния трафик.

Проблема в горният скрипт е че при четене на IР-тата от FILENAME за целия масив запомня (т.е. за всички юзери) запомня първото IP и първия максимален трафик.

Та въпроса ми е: Къде съм сбъркал?

Опознай Linux за да го обикнеш!
Отговор
в отговор на mimosh #2

Re: Bash script помощ ако може

ako ne gresha
vuv:
while [ $i -lt $count ]; do
IP=( "${IP[@]}" "${array1}" ) <-------------- tuka
max_traff=( "${max_traff[@]}" "${array1[i+1]}")

zameni s :
IP=( "${IP[@]}" "${array1}" )


DrFrancky

Отговор
в отговор на mimosh #3

Re: Bash script помощ ако може

няма ли да ти е по-удобно ако вместо с масиви си намираш лимита с нещо от сорта на:
limit=`grep $user_ip $FILENAME | awk '{print $2}'`

Отговор
в отговор на DrFrancky #4

Re: Bash script помощ ако може

Той го има това. Ама [ i ] е начало на италик, та затова не излиза.

Отговор
в отговор на пинrвин-лeшoяд #5

Re: Bash script помощ ако може

В отговор на:

Ама [ i ] е начало на италик, та затова не излиза.



а за да излезе, трябва някой да сложи [pre ] отпред...

TANSTAAFL! There AiNt Such Thing As A Free Lunch
Отговор
в отговор на onzi #7

Re: Bash script помощ ако може



test
test



не помага, първото е
test [ i ]

Отговор
в отговор на mn_t #8

Re: Bash script помощ ако може

мдам. значи остава да се слагат интервали в квадратните скоби

TANSTAAFL! There AiNt Such Thing As A Free Lunch
Отговор
в отговор на onzi #9

може и без интервали

* [i][/i]
* [b][/b]

- [b][[[b/]/b]i][b][[[b/]/b]/i]

Satan`s Defloration Incorporated
Отговор
в отговор на ЛУД ПPЪЧ #10

Re: може и без интервали

За можене може, ама трябва да се претърсва текста за да се подменят всички [i]-та Ето и от мен едно. Който го мързи да слага b-та или i-та вместо black:
[[black]i[/black]] = [i]

Отговор
в отговор на пинrвин-лeшoяд #11

Re: може и без интервали

malko izmestihme temata ...

ako picha se oste se nuzdae ot pomost da paste link kadeto ima TXT file s scripta ili pone text page ...

DrFrancky

Отговор
в отговор на DrFrancky #12

Re: Bash script помощ ако може

Благодаря на всички.

Докторе благодаря за своевременния отговор, обаче не виждам разлика в твоя и в моя ред.
И аз си мисля че точно това което е посочил доктора точно то не работи обаче експериментирах как ли не със синтаксиса и не се получава и не се получава.
Някой ми спомена че възможна причина в случая може да е символа за край на ред в текстовия файл, ама не знам какъв трябва да бъде и какъв е.
Ако някой може да помогне.


няма ли да ти е по-удобно ако вместо с масиви си намираш лимита с нещо от сорта на:
limit=`grep $user_ip $FILENAME | awk '{print $2}'`

Ами не знам аз го направих така защото исках всяка операция да бъде отделена. В смисъл първо блок за четене на юзери после блок за четене на трафик, дата и т.н., а ако беше така както ти казваш трябваше това всичкото да си върви подред както е в момента с......

абе може и така

Опознай Linux за да го обикнеш!
Отговор
в отговор на mimosh #13

Re: Bash script помощ ако може

tam kadeto ispolzvam [i ] ima space sled i-to za da izbegna italic-a na foruma

tam kadeto pravis select v bazata ne triabva li IP da e masiv ? t.e ${IP[i ]} ?
i oste nesto :
array1=( `cat "$FILENAME"`)
count=${#array1[*]}
i=0
ii=0

while [ $i -lt $count ]; do
IP=( "${IP[@]}" "${array1[i ]}" )
max_traff=( "${max_traff[@]}" "${array1[i+1]}")
let i=i+2
let ii=ii+1
done
echo ${IP[0]}
echo ${IP[1]}
echo ${IP[2]}

tova si raboti

postavi si echo-ta na kluchovi mesta za debug

DrFrancky

Отговор
в отговор на DrFrancky #14

Re: Bash script помощ ако може

> mdaa :-)) lame error ot moia strana :-))

> zalka kartinka :-)) mnogo zalka :-))



Отговор
в отговор на пинrвин-лeшoяд #15

Re: Bash script помощ ако може

Малко но не маловажна коеркция!
limit=`grep $user_ip $FILENAME | awk '{print $2}'` <- това е некоректно

ако във $FILENAME имаш нещо от сорта на:
192.168.0.3 1000
192.168.0.34 1000
192.168.0.39 1000
192.168.0.30 1000

то резултата на написания от теб ред ще е:
192.168.0.3
192.168.0.34
192.168.0.39
192.168.0.30

добре би било този ред:
limit=`grep $user_ip $FILENAME | awk '{print $2}'`
да се запише поне така:
limit=`grep "$user_ip " $FILENAME | awk '{print $2}'`

Отговор
в отговор на DrFrancky #16

Re: Bash script помощ ако може

В подобни ситуаци много удобно се работи с:
for var in $db
do
...
done

Пример:

n=0
ALL_IP=`cat ${FILENAME} | awk '{ print $1 }'`
for IP in $ALL_IP; do
array1[$n]="${IP}"
array2[$n]=`grep "${IP} " ${FILENAME} | awk '{ print $2 }'`
let n=n+1
done

Отговор