пятница, 28 января 2011 г.

Bash-скрипт для опроса сети

Предисловие
Покупая автомобиль, не забывайте об окружающей среде и выхлопных газах, которыми приходится дышать людям. Технология SCR и реагент Ad blue, уменьшающий вред отработанных газов, распространены в Европе и постепенно приходят в Россию.

Это пост будет коротким и без скриншотов. Bash и картинки не совместимы (: Для отображения состояния компьютеров понадобится скрипт, который будет опрашивать сеть по определенному списку и в нем же отмечать онлайн/оффлайн.
Текстовый файл ("ip_net") с перечнем компьютеров будет выглядеть так:

адрес_имя состояние
адрес_имя состояние
...

К примеру:

192.168.200.3_Ком.сервер 0
192.168.200.15_Файл-север 1

где 0 - оффлайн, 1 - онлайн.

Текст bash-скрипта:

#!/bin/bash

IPFILE="$HOME/LuaConky/ip_net"
TMPFILE="$HOME/LuaConky/tmpnet"
> $TMPFILE
cat "$IPFILE" | while read IPNAME
do
IP=${IPNAME%"_"*}
NAME=${IPNAME#*"_"}
NAME=${NAME%" "*}
echo $IP"_"$NAME `ping -c 1 $IP | grep -c "1 received"` >> $TMPFILE
done
cat $TMPFILE > $IPFILE
exit

Стандартное начало - "#!/bin/bash". Затем следует присвоение переменным путей до файлов "ip_net" (должен быть создан заранее) и "tmpnet" (создается в процессе).
Строчка "> $TMPFILE" очищает файл "tmpnet".
Далее идет цикл пока не кончатся строки в файле "ip_net" ("cat "$IPFILE" | while read IPNAME"). За один проход читается одна строка из которой в переменную IP записывается адрес компьютера, а в NAME - его имя.
Ping при отрицательном результате (пакет не прошел) в выдаче имеет "0 received", при положительном - "1 received", поэтому можно ориентироваться по этому сочетанию. Что и делает "ping -c 1 $IP | grep -c "1 received"", здесь с помощью "grep" подсчитывается количество вхождений (ключ -c) сочетания "1 received" в выдаче "ping". И, если не находит, записывает ноль.
Полное формирование строки ("echo $IP"_"$NAME `ping -c 1 $IP | grep -c "1 received"` >> $TMPFILE") записывается в файл "tmpnet".
По окончании цикла в "ipnet" записываются строки из "tmpnet".
Такой вот получился скрипт. Конечно, профессионалы могут написать код и покороче (комментарии приветствуются), но, что вышло, то вышло. Главное работает (:


Смотри также

4 коммент.:

  1. На мой взгляд особо добавить нечего. Ну я бы переменные именовал на в caps, потому как такой формат часто используется для constant, которыми по сути в скрипте являются лишь IPFILE и TMPFILE. Я бы использовал кавычки во всех операциях с файлами, потому как текущая запись не позволит использовать имена с пробелами:
    cat "${TMPFILE}" > "${IPFILE}"
    Последняя конструкция мне кажется слегка неизящной :) Почему нельзя просто
    cp "${TMPFILE}" "${IPFILE}"
    Зачем все время хранить на диске TMPFILE?
    Ну и быть может для парсинга в bash я бы использовал =~:

    cat "$IPFILE" | while read IPNAME ; do
    [[ "${IPNAME}" =~ ^([^_]*)_([^ ]*).*$ ]]
    IP=${BASH_REMATCH[1]}
    NAME=${BASH_REMATCH[2]}

    Но в случае двух переменных выигрыш невелик.

    Так что в общем все нормально - главное, чтобы действительно работал :)

    ОтветитьУдалить
  2. Очепятки:
    s/именовал на в caps/именовал не в caps/g

    ОтветитьУдалить
  3. Beggy, спасибо за замечания. Просто опыт работы с bash'ем у меня чуть более, чем нулевой, и один раз получив что-то рабочее продолжаю копировать это дальше.
    А конструкции вида "[[ "${IPNAME}" =~ ^([^_]*)_([^ ]*).*$ ]]" пока остаются загадочными. Но будем учиться (:

    ОтветитьУдалить
  4. АнонимныйJun 25, 2011 03:52 PM

    #!/bin/bash

    is_alive_ping()
    {
    ping -c 1 $1 > /dev/null
    [ $? -eq 0 ] && echo Node with IP: $i is up.
    }

    for i in 10.0.0.{1..255} #указываем сканируемую сеть
    do
    is_alive_ping $i & disown
    done

    echo DONE

    ОтветитьУдалить