Форум Gatchina OnLine

Форум Gatchina OnLine (https://forumgol.ru/index.php)
-   Программирование и разработка (https://forumgol.ru/forumdisplay.php?f=4)
-   -   Скрипт на баше (https://forumgol.ru/showthread.php?t=11547)

TNT 22.05.2011 15:34

Скрипт на баше
 
Нужно написать скрипт на bash/ksh. Нужно вывести все системы, имеющие IP адрес в подсетях исходной системы и отвечающие на ARP запросы, потом вывести информацию об использовании дискового пространства локальных файловых систем.

Т.к. я хреново это все знаю, то намутил кучу и уже запутался.
Просьба не обращать внимания на кучу лишних переменных, знаю, что убрать можно много.
Код:


#! /usr/bin/ksh

#подсчет количества подсетей
netcount=`ifconfig -a | sed -n $q"p" | awk '{if($5=="broadcast") print $2}' | wc -l`


i=1

while [ $i -le $netcount ]
do

#выборка маски
ifconfig -a | awk '{if($5=="broadcast") print $4}' | tr '[a-f]' '[A-F]' | read a
echo "ibase=16;$a"|bc | read mask

#выборка адреса подсети
ifconfig -a |  awk '{if($5=="broadcast") print $2}' | read NET
net=`echo $NET`
n1=`echo $net | awk -F"." '{print $1}'`
n2=`echo $net | awk -F"." '{print $2}'`
n3=`echo $net | awk -F"." '{print $3}'`
n4=`echo $net | awk -F"." '{print $4}'`
net=`expr $n1 \* 16777216 + $n2 \* 65536 + $n3 \* 256 + $n4`

#расчет последнего адреса в сети, то же самое, что 2^32-1
max=`expr 255 \* 16777216 + 255 \* 65536 + 255 \* 256 + 255`

#расчет количества хостов
host=`expr $max - $mask`


#подсчет первого адреса в подсети: адрес бродкаста минус количество хостов
ifconfig -a | sed -n $q"p" | awk '{if($5=="broadcast") print $6}' | read startip

n1=`echo $startip | awk -F"." '{print $1}'`
n2=`echo $startip | awk -F"." '{print $2}'`
n3=`echo $startip | awk -F"." '{print $3}'`
n4=`echo $startip | awk -F"." '{print $4}'`

startip=`expr $n1 \* 16777216 + $n2 \* 65536 + $n3 \* 256 + $n4`

start=`expr $startip - $host`


end=`expr $net + $host - 1`


j=$start
while [ $j -le $end ]
 do
 a1=`expr $j / 16777216`
 r=`expr $j % 16777216`
 a2=`expr $r / 65536`
 r=`expr $r % 65536`
 a3=`expr $r / 256`
 a4=`expr $r % 256`

#обновление ARP таблицы
 echo "ping $a1.$a2.$a3.$a4 ..."

arp $a1.$a2.$a3.$a4 >>log
if [ $? -eq 0 ]
then
echo "Disk space of local filesystems on $a1.$a2.$a3.$a4:"
rsh $j df -l
fi
j=`expr $j + 1`
done
i=`expr $i + 1`
done

Вот перебор по подсетям я и не вкупаю как сделать. Моя куча-мала три раза перебирает первую подсеть и все.
100 пудов это все пишется, конечно, гораздо короче и менее запутано. Если кто подскажет - буду очень признательный.

VK 22.05.2011 15:42

у тебя в первой же строчке ошибка, если в системе два адреса из одной сети - он тебе выдаст не одну сеть, а две. если пять - то пять.
с остальным не разбирался, запутано у тебя все.

TNT 22.05.2011 15:50

Запутано - не то слово...
Скрипт знакомый писал, потом я его еще мучал.

В первой строчке ключ -l не дописал к wc. Вообще, выводит правильно - на три подсети три записи.

VK 22.05.2011 15:52

а на три сети, но пять адресов?

TNT 22.05.2011 16:00

Я так понимаю, вот эта строчка имеется в виду:

ifconfig -a | awk '{if($5=="broadcast") print $2}' | wc -l

Так после awk же остаются только бродкаст-адреса, т.е. их в любом случае столько же, сколько подсетей.
Три я написал потому, что там, где скрипт исполняется их три, а адресов то там прилично.

VK 22.05.2011 16:04

$ ifconfig -a | awk '{if($5=="broadcast") print $2}'
192.168.10.250
192.168.11.250
192.168.10.111
192.168.11.111
85.114.xxx.xxx

вывело пять, хотя сетей всего три.
при этом есть еще два tun интерфейса от openvpn, в которых отсутствует broadcast и соответственно скрипт о них ничего не узнает :)

VK 22.05.2011 16:08

в общем, эту строчку, изначально кривую, надо заменить вот этим - ifconfig -a | grep broadcast |sort -u +5 |wc -l
у меня на freebsd работает правильно.

TNT 22.05.2011 16:11

Благодарю :) Я хреново в этом разбираюсь :)
То есть бродкаст-адресов может быть больше, чем сетей? Я думал, что для каждой сети может быть только по одному бродкасту: адрес сети с маской.

VK 22.05.2011 16:15

броадкаст выводится на каждый адрес, вне зависимости от того, есть ли еще адреса из этой сети в системе или нет.
а вообще завязываться на ifocnfig опасно, так как его вывод не стандартизирован и то, что у меня работает правильно на фре, может не сработать на линухе... правда как сделать по-другому пока не знаю :)

TNT 22.05.2011 16:23

Мне надо, чтобы на Солярисе работало :) В общем-то, должно.

На ifconfig завязываться нужно - попросили именно так делать. А вообще, по идее, можно еще из hosts вытащить. Но сказано не делать. Хотя, если есть третий способ без hosts, думаю, должно прокатить.

VK 22.05.2011 16:29

я это к тому сказал, что на твоем солярисе ifconfig может иметь иной вывод и соответственно скрипт будет работать неверно.

TNT 22.05.2011 16:30

Да, я понял. Но в нем проблем нет - все правильно выводится.

Вождь 22.05.2011 17:49

можно вместо ifconfig юзать ip a, оно вроде более стандартизировано

VK 22.05.2011 17:56

$ ip a
-bash: ip: command not found

TNT 22.05.2011 17:58

$ ip a
ksh: ip: not found
:)

Потихоньку начал раскуривать, решил все заново писать.

ΛLIEN 22.05.2011 20:26

Ну так во фряхе или соляре iproute2 нет. Откуда ip тогда взяться.

VK 22.05.2011 21:13

это была демонстрация несостоятельности заявления, что "ip a более стандартизировано".

Вождь 22.05.2011 22:29

это бало не заявление а предположение

TNT 22.05.2011 23:47

Переписал в итоге все, вроде работает. Если проканает - напишу, как сделать, вдруг кому надо.

ΛLIEN 23.05.2011 01:36

Цитата:

Сообщение от TNT (Сообщение 416071)
Переписал в итоге все, вроде работает. Если проканает - напишу, как сделать, вдруг кому надо.

Сомневаюсь, что без напильника это заработает под линухом, как раз из-за нестандартного вывода ifconfig.

VK 23.05.2011 01:49

Цитата:

Сообщение от ΛLIEN (Сообщение 416077)
Сомневаюсь, что без напильника это заработает под линухом, как раз из-за нестандартного вывода ifconfig.

в том-то и дело, что стандартов на это нет.
но дело даже не в этом, вряд ли это кому-то может понадобиться еще :) это плод больного воображения препода и только. к жизни отношения не имеющий.

TNT 24.05.2011 21:03

Цитата:

Сообщение от VK (Сообщение 416078)
это плод больного воображения препода и только. к жизни отношения не имеющий.

Именно так. Слабо понимаю, нахрен это надо.

FeD 24.05.2011 21:22

Цитата:

Сообщение от TNT (Сообщение 416170)
Слабо понимаю, нахрен это надо.

а зачем в школе на бэйсике пишут проги для решения квадратных уравнений? это тоже бред больного воображения? ведь можно ж в калькуляторе посчитать

TNT 24.05.2011 22:33

Плохой пример, это разные вещи.

TNT 25.05.2011 15:04

В общем, сделал все заново так (вдруг кому интересно):

Код:

#!/bin/bash
# Additional functions
# Decimal to binary
binary=0
decToBin(){
        binary=`echo $1 | gawk -F. '{OFMT = "%.10g"; print $1*2^24+$2*2^16+$3*2^8+$4}'`
}

#Binary to decimal
decimal=0.0.0.0
binToDec(){
        decimal=`echo $1 | gawk '{ 
                                  temp = $1;
                                  for (i = 1; i<=4; i++){
                                        IP[i] = temp%2^8;
                                        temp = int(temp/2^8);
                                  }
                                  print IP[4]"."IP[3]"."IP[2]"."IP[1] 
                                }'`
}

# Part A Getting list of subnets and their masks.
subnets=(` ifconfig -a | grep broadcast | gawk '{print $2}'`)
count=${#subnets[*]}

#Part B Updating ARP table
i=0

while [ $i -lt $count ]
do
        net=`netstat -rnv | gawk '$3 == "'${subnets[$i]}'" {print $1}' | grep -v  224 `
      mask=` netstat -rnv | gawk '$3 == "'${subnets[$i]}'" {print $2}' | grep -v 240`
        decToBin $net
        net=$binary;
        decToBin $mask
        mask=$binary;

        comp=1;       
        limit=`echo 2^32 - $mask - 1 | bc`;
       
        while [ $comp -lt $limit ]
        do
          ip=`echo $net + $comp | bc`;
          binToDec $ip;
          ping $decimal 1;
                if [ $? -eq 0 ]
                then
                  rsh $decimal df -l;
                fi
          let "comp+=1";

        done
        let "i+=1";
done

Пингует и, если пинг удачный, пытается сделать df.

VK 25.05.2011 21:05

что-то твое решение хреново совпадает с твоим же условием в первом посте :) и строчку с ifconfig ты переделал опять до того же некорректно работающего состояния :) sort там был не просто так.

TNT 25.05.2011 22:38

А почему с условием не совпадает? Вроде нормательно: обновляет ARP-таблицу, как только пинг прошел - берет информацию df -l.

Да, кстати, насчет сорта: я так и не врубил, зачем был он нужен... :)

VK 25.05.2011 22:40

"вывести... отвечающие на ARP-запросы". ping - это не arp-запрос, ответ на пинг может быть и не получен, а arp вполне.
sort нужен был для того, чтобы исключить дублирующиеся сети.

VK 25.05.2011 22:45

короче, вот это:
Цитата:

ping $decimal 1;
if [ $? -eq 0 ]
then
rsh $decimal df -l;
fi
надо переделать вот так:
arp $decimal >/dev/null && rsh $decimal df -l;

и все.

TNT 25.05.2011 22:50

Ну в принципе тоже верно.
А чем плоха проверка потока с ошибками? Просто не самый эффективный метод?

VK 25.05.2011 22:51

не понял вопрос :)

TNT 25.05.2011 22:56

Ну эти два варианта эквивалентны, разве нет?
Я повторюсь: фигово в этом разбираюсь, поэтому разницы и не вижу.

А пинг я делал для того, чтобы просто обновить ARP-таблицу на самом деле. Она, насколько мне известно, только так обновляется.

VK 25.05.2011 23:06

Цитата:

Сообщение от TNT (Сообщение 416255)
Ну эти два варианта эквивалентны, разве нет?
Я повторюсь: фигово в этом разбираюсь, поэтому разницы и не вижу.

если абстрагироваться от ping vs arp - эквивалентны, но мой вариант более правилет с точки зрения баш-программизма :) не говоря о том, что более понятен.
Цитата:

Сообщение от TNT (Сообщение 416255)
А пинг я делал для того, чтобы просто обновить ARP-таблицу на самом деле. Она, насколько мне известно, только так обновляется.

man arp :)

TNT 25.05.2011 23:09

Хокай, спасибо :)

ΛLIEN 27.05.2011 01:45

Цитата:

decToBin(){
binary=`echo $1 | gawk -F. '{OFMT = "%.10g"; print $1*2^24+$2*2^16+$3*2^8+$4}'`
}
Как-то твоя функция неправильно переводит ip адрес
192.168.1.1 = C0.A8.01.01 = 0xC0A80101 = 3232235777
Твоя же вывела у меня 272891929 -> 16.68.00.25

зы: как вариант

Код:

decToBin(){
  binary=$(echo ibase=16\;$(printf '%02X' ${1//./ }) | bc)
}

$ip=192.168.1.1
decToBin $ip
echo $binary


TNT 27.05.2011 13:04

Да, в старой версии тоже делал через ibase, накосячить сложнее.
Спасибо за поправку :)


Текущее время: 13:11. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2025, vBulletin Solutions, Inc. Перевод: zCarot