Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: never_mind в Jan 28, 2008, 10:51



Титла: Помощ за скрипт
Публикувано от: never_mind в Jan 28, 2008, 10:51
Добър ден. Идеята е следната. Имам списък с мрежи, но в cisco формат, тоест с обратна маска ( пример 0.0.31.255 ). Искам да го преобразувам автоматично в списък с нормална CIDR маска, ( пример /19 ). Намерих инструмента calcmask, който прави следното:

Примерен код
#calcmask wildcard 0.0.31.255
     CIDR mask: 19
       Netmask: 255.255.224.0
Cisco wildcard: 0.0.31.255


Така, до тук добре, но следва трудна част за мен.

от следният ред
Примерен код
77.45.45.45 0.0.31.255

аз трябва да получа
Примерен код
77.45.45.45/19

за да може pf да го разпознае... и това трябва да става автоматично чрез скрипт... и то за всеки един ред от списъка... явно ще има цикъл, който обхожда всеки ред... и замества обратната маска с CIDR, като я взима от изхода на програмата... Идеи?


Титла: Помощ за скрипт
Публикувано от: shadowx в Jan 28, 2008, 11:12
Примерен код

#!/bin/bash

ip=$1
mask=$2

      if [ -z $ip ]
         then
                echo -e "Usage: $0 <ip> <mask>"
                exit 0
      fi

      mask=`calcmask wildcard $mask | grep CIDR | awk '{print $3}'`

      echo -e "$ip/$mask"

exit 0






Титла: Помощ за скрипт
Публикувано от: never_mind в Jan 28, 2008, 23:09
Мерси много. Работи перфектно. Мисля да се помъча сам за останалата част, набарах една книга и ще я прочета цялата, специално за шел скриптинга... после ще постна крайният ми скрипт... :)


Титла: Помощ за скрипт
Публикувано от: zeridon в Jan 29, 2008, 17:04
Като свършиш публикувай го моля те в ето тази категория: http://www.linux-bg.org/cgi-bin....t=21864


Титла: Помощ за скрипт
Публикувано от: never_mind в Jan 29, 2008, 18:11
баси, единствената спъкна е да отделя определен ред... не мога нито с tail, нито с cat...
п.с сичко е 6 вече





Титла: Помощ за скрипт
Публикувано от: bubu в Jan 29, 2008, 18:56
awk или sed не ти ли вършaт работа ? Дай да го видим този ред и ще помислим как може да го отделиш :)


Титла: Помощ за скрипт
Публикувано от: never_mind в Jan 29, 2008, 19:17
Примерен код
#!/bin/bash
wget http://www.nat.bg/look/AS/ip-access-src.txt && cat ip-access-src.txt | grep permit > temp && cat temp | cut -f5,6 -d" " > unconverted && cat unconverted | wc -l > line_cnt
lines=$(cat line_cnt)
i=1
while (( i <= $lines ))
do
        head -n$i unconverted | tail -n1 > temp_convert
        ip=$( cat temp_convert | awk '{print $1}')
        mask=$( cat temp_convert | awk '{print $2}')
        mask=`calcmask wildcard $mask | grep CIDR | awk '{print $3}'`
        echo "$ip/$mask" >> bgpeering
        let i=i+1
done
rm ip-access-src.txt temp unconverted line_cnt temp_convert
cp bgpeering /etc/ && pfctl -f /etc/pf.conf

Аз стигнах до това. Сигурно може да се оптимизира, затова предлагайте :)


Титла: Помощ за скрипт
Публикувано от: shadowx в Jan 29, 2008, 20:17
100% има доста по-добри от моя варянт , но лично аз бих го написал така :
Примерен код

#!/bin/bash
n="1"
tmp="/tmp/tmpfile"
bgpeering="bgpeering"

    if [ -e $tmp ]; then rm -f $tmp; fi
    if [ -e ip-access-src.txt ]; then rm -f ip-access-src.txt; fi

        wget http://www.nat.bg/look/AS/ip-access-src.txt
        cat ip-access-src.txt | grep permit | cut -f5,6 -d" " >> $tmp

    lines=`cat $tmp | wc -l`

        while [ $n -le $lines ]
           do

              ip=`head -n$n $tmp   | tail -n1 | awk '{print $1}'`
              mask=`head -n$n $tmp | tail -n1 | awk '{print $2}'`
              mask=`calcmask wildcard $mask | grep CIDR | awk '{print $3}'`

                if [ -e $bgpeering ]; then rm -f $bgpeering; fi

              echo -e "$ip/$mask" >> $bgpeering

              let "n = $n + 1"

        done


    rm -f ip-access-src.txt
    cp -f $bgpeering /etc/
    pfctl -f /etc/pf.conf

exit 0


Титла: Помощ за скрипт
Публикувано от: Hapkoc в Jan 29, 2008, 20:18
while read line; do
    # process line here ...
done < filename

(моите 2 ст.)


Титла: Помощ за скрипт
Публикувано от: never_mind в Feb 06, 2008, 10:14
Нещо не мога да го направя с while read line... мисля, че ми интерпретира целия файл като 1 ред... понеже използвайки това
Примерен код

while read line; do
        ip=`awk '{print $1}'`
        mask=`awk '{print $2}'`
echo "$ip/$mask\n" >> bgpeering
done < unconverted


изхода ми е
Примерен код

123.132.123.0
123.132.133.0
....
....
123.233.132.0/\n <- това е последният ред

тоест маската изобщо не я хваща...
A пък при
Примерен код

while read line; do
        ip=`awk '{print $1}'`
echo $ip > ip
done < unconverted

файлът ip съдържа всички ip-та, като 1 ред...

Иначе това ми е финалната версия на скрипта... засега...


 
Примерен код

umask 022

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin

cd /etc
i="1"
        if [ -e ip-access-src.txt ]; then rm -f ip-access-src.txt; fi
        if [ -e bgpeering ]; then rm -f bgpeering; fi
wget http://www.nat.bg/look/AS/ip-access-src.txt && cat ip-access-src.txt | grep permit | cut -f5,6 -d" " > unconverted
lines=$(cat unconverted | wc -l)
i=1
while (( i <= $lines ))
do
        head -n$i unconverted | tail -n1 > temp_convert
        ip=$( cat temp_convert | awk '{print $1}')
        mask=$( cat temp_convert | awk '{print $2}')
        mask=`calcmask wildcard $mask | grep CIDR | awk '{print $3}'`
        echo "$ip/$mask" >> bgpeering
        let i=i+1
done






Титла: Помощ за скрипт
Публикувано от: Hapkoc в Feb 06, 2008, 15:29
Имах предвид нещо от рода на:

while read line; do
  ip=$( echo $line | awk '{ print $1 }' )
  mask=$( echo $line | awk ... )
done < filename

В случая line е променливата, в която е прочетен реда от файла.

Както и да е, просто отбелязах, в крайна сметка по-важното в някои случаи е да работи, не как е написано. :)


Титла: Помощ за скрипт
Публикувано от: never_mind в Feb 06, 2008, 16:42
Да, прав си, но аз по принцип обичам всичко да е максимало оптимизирано и правилно написано. Твоят вариант стана така:
Примерен код
umask 022

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin

cd /etc
        if [ -e ip-access-src.txt ]; then rm -f ip-access-src.txt; fi
        if [ -e bgpeering ]; then rm -f bgpeering; fi
wget http://www.nat.bg/look/AS/ip-access-src.txt && cat ip-access-src.txt | grep permit | cut -f5,6 -d" " > unconverted
while read line
do
        ip=$( echo $line | awk '{print $1}')
        mask=$( echo $line | awk '{print $2}')
        mask=`calcmask wildcard $mask | grep CIDR | awk '{print $3}'`
        echo "$ip/$mask" >> bgpeering
done < unconverted

което е доста по-малко код и по-добре написано... въпреки, че не се постига бързодействие на скрипта ( и в този вариант отнема около 40-50 сек за конвертиране на всичките над 500 мрежи ). Засега това е актуалната версия на скрипта :)


Титла: Помощ за скрипт
Публикувано от: radoulov в Feb 07, 2008, 13:15
Цитат (never_mind @ Фев. 06 2008,17:42)
Да, прав си, но аз по принцип обичам всичко да е максимало оптимизирано и правилно написано.

В такав случай използвай повече shell и по-малко external utilities:

Примерен код
umask 022

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin

while read a y p i ip mask f;do
    [ "$p" = "permit" ]&&printf "%s/%s\n" "$ip" "$({ read;printf "${REPLY##* }";}\
    < <(calcmask wildcard "$mask"))"
done< <(curl -s http://www.nat.bg/look/AS/ip-access-src.txt)>/etc/bgpeering


P.S. Ако имаш bash compiled с --enable-net-redirections можеш да пробваш без curl/wget:

Примерен код
umask 022

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin

exec 3<>/dev/tcp/www.nat.bg/80

printf "GET /look/AS/ip-access-src.txt HTTP/0.9\n\nConnection: close\n">&3

while read a y p i ip mask f;do
   [ "$p" = "permit" ]&&printf "%s/%s\n" "$ip" "$({ read;printf "${REPLY##* }";}\
   < <(calcmask wildcard "$mask"))"
done<&3>/etc/bgpeering

exec 3>&-






Титла: Помощ за скрипт
Публикувано от: never_mind в Feb 08, 2008, 21:43
Доста съм зле все още с тази материя... и ти ме разби... в момента се опитвам да разбера всяко едно нещо от твоите предложения какво прави всъщност и донякъде успявам... :)
Можеш ли да ми препоръчаш някакво четиво... но наистина подробно и цялостно... виждам, че си на ти с скриптовете... :)
btw версиятата ти работи и то ужасно бързо... :)





Титла: Помощ за скрипт
Публикувано от: radoulov в Feb 08, 2008, 23:16
Разбира се,
няколко задължителни (по мое мнение) четива:

Bruce Barnett's tutorials on UNIX shell programming and various other arcane subjects

Advanced Bash-Scripting Guide by Mendel Cooper

За по-напреднали:

Effective AWK Programming by Arnold Robbins

A User's Guide to ZSH

Надявам се да са ти полезни,
както бяха (и все още са) за мен.

P.S. Изключително са важни и някой форуми и news groups,
но не знам, дали е уместно да поствам подобни линкове тук.