Как освоить програмирование на bash

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Ответить
Аватара пользователя
sunny1983
Сообщения: 357
ОС: GNU/Linux 4.x (Fedora, Debian)
Контактная информация:

Как освоить програмирование на bash

Сообщение sunny1983 »

Не получается освоить програмирование на bash. Язык для меня сложен тем что: 1) вместо зарезервированых слов в нём в массе используются спецсимволы такие как "[", "$", которые имеют двоякое и троякое значение, 2) нет функций по обработке строк, вместо этого предлагается использовать sed и awk, синтаксис которых довольно запутан.
Подумалось, а не бросить ли этот bash, и не заняться ли изучением продвинутых скриптовых языков. Вот только можно ли в других языках также легко перенаправлять вывод в stdout одной программы на вход stdin другой программы.
Есть две задачи.

Задача 1: нужно реализовать сканирование сети, с целью выявить все хосты по MAC-адресу. Для этого на компьютере создан bridge-интерфейс, команда "brctl showmacs" отображает MAC-адреса всех устройств, после делается перебор командой arp, которая перебирает все ip-адреса, которые могут входить в подсеть:

Код: Выделить всё

IF=br0
brctl showmacs $IF | awk '{print $2}' | grep ":" | while read MACADDR
do
   for IPADDR in "$IPVARIANTS"
   do
      if [[ -n "$(arp -n "$IPADDR" | grep "$MACADDR")" ]]; then
         IPADDRTRUE=true
         echo -e "$MACADDR \t $IPADDR"
      fi
   done
   if [[ IPADDRTRUE != true ]]; then
      echo -e "$MACADDR \t no ip address"
   fi
done

Знаю, что задача переборки двух строковых массивов выполняется совсем не так, но как средствами bash это сделать более правильно - я не сообразил, лучше конечно не вызывать цикл arp для каждого MAC-адреса, а сделать это один раз, а ещё не сообразил как задать переменную IPVARIANTS - в ней должны быть перечислены все ip-адреса через пробел, входящие в заданную подсеть, например в подсеть 128.0.0.0/22

Задача 2: нужно реализовать автовход по ssh или telnet на свитчи. Авторизация по ключу не поддерживается, то есть нужно сделать, чтобы скрипт передавал логин и пароль прямо в терминал устройства, вставляя в передачи паузы нужной длины. Но сначала нужно, чтобы терминал устройства вообще как-то открывался. Есть windows-программа The Dude, которорая работает в wine, программа представляет собой карту сети и, кликнув на любое устройство на карте, можно на него зайти. wine позволяет запускать bash-скрипты, если им присвоено расширение exe. У меня в настройках The Dude прописан вызов инструмента "c:\ssh.exe root@[Device.FirstAddress]", то есть при заходе на устройство 128.0.0.3 должен вызываться скрипт ssh.exe c параметром root@128.0.0.3, мне хотелось, чтобы этот скрипь вызывал окно эмулятора терминала с запущеным в нём клиентом ssh

Код: Выделить всё

#!/bin/bash
/usr/bin/xfce4-terminal -x "/usr/bin/ssh $1"

ssh-сессия не открывается, окно эмулятора терминала появляется на экране и тут же изчезает, я не успеваю прочитать, что на него выводится. А как в этом скрипте реализовать ещё и автовход - вообще не знаю.
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Как освоить програмирование на bash

Сообщение SLEDopit »

sunny1983 писал(а):
25.07.2016 11:13
Задача 1:
У вас в цикле значение IPADDRTRUE не сбрасывается. Поэтому после первого срабатывания оно всегда будет true. Перед for'ом выставляйте его в false или другое значение.
Но в целом не очень понятно зачем это нужно. Почему просто список IP из IPVARIANTS нельзя опросить?
Если оно не знает про такой, оно так и скажет:

Код: Выделить всё

 # arp -n XX.XX.50.189
XX.XX.50.189 (XX.XX.50.189) -- no entry

Зачем весь этот сыр-бор с brctl showmacs?

sunny1983 писал(а):
25.07.2016 11:13
Задача 2
Но ведь есть expect. Как раз для подобных случаев. Зачем так извращаться с wine? :)

И да, sed/awk не такие уж и страшные: sed + awk. После этих пособий всё предельно понятно.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как освоить програмирование на bash

Сообщение Bizdelnick »

sunny1983 писал(а):
25.07.2016 11:13
предлагается использовать sed и awk, синтаксис которых довольно запутан.

А Вы не используйте. Они требуют отдельного изучения и прямого отношения к bash не имеют. А суют их где ни попадя чаще всего по незнанию, что имеются более простые (но менее гибкие) средства. Например, вместо
sunny1983 писал(а):
25.07.2016 11:13

Код: Выделить всё

brctl showmacs $IF | awk '{print $2}'
куда проще использовать

Код: Выделить всё

brctl showmacs $IF | cut -f2


sunny1983 писал(а):
25.07.2016 11:13
Знаю, что задача переборки двух строковых массивов выполняется совсем не так

Если Вы считаете, что тут нужны массивы, почему Вы их не используете?

sunny1983 писал(а):
25.07.2016 11:13
не сообразил как задать переменную IPVARIANTS - в ней должны быть перечислены все ip-адреса через пробел, входящие в заданную подсеть, например в подсеть 128.0.0.0/22

Не обязательно через пробел, подойдёт любой разделитель из $IFS. Но задачка действительно не из простых. Можно облегчить её, если задавать не адрес сети с маской, а диапазон адресов.

sunny1983 писал(а):
25.07.2016 11:13
нужно сделать, чтобы скрипт передавал логин и пароль прямо в терминал устройства, вставляя в передачи паузы нужной длины.

Не нужно никуда вставлять никаких пауз.

Код: Выделить всё

ssh $RUSER@$RHOST $COMMAND << EOF
$RPASSWORD
EOF

А ещё проще прописать логин с паролем в ~/.netrc.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
sunny1983
Сообщения: 357
ОС: GNU/Linux 4.x (Fedora, Debian)
Контактная информация:

Re: Как освоить програмирование на bash

Сообщение sunny1983 »

SLEDopit писал(а):
25.07.2016 12:08
Зачем весь этот сыр-бор с brctl showmacs?

Затем, что если устройство работает на 2-м уровне (IP-адрес не использует) то arp его не обнаружит, а brctl showmacs обнаружит.
У меня больше вопрос как IPVARIANTS получить.



SLEDopit писал(а):
25.07.2016 12:08
Но ведь есть expect. Как раз для подобных случаев. Зачем так извращаться с wine? :)

Затем, что The Dude в сети был внедрён до меня и меня это устраивает. До меня правда на всех рабочих станциях винда стояла. Я только хочу автоматизировать процесс управления свитчами, не вбивать ip-адрес в терминале, а кликать по карте, под виндой это работает - там просто PuTTY запускается с автовходом. если кто-нибудь мне объяснил как expect к bash-скрипту прибить.
Спасибо сказали:
Аватара пользователя
sunny1983
Сообщения: 357
ОС: GNU/Linux 4.x (Fedora, Debian)
Контактная информация:

Re: Как освоить програмирование на bash

Сообщение sunny1983 »

Bizdelnick писал(а):
25.07.2016 12:33
Если Вы считаете, что тут нужны массивы, почему Вы их не используете?

Мне казалось, что в bash вообще нет такого понятия как строковые массивы, есть костыли позволяющие обрабатывать строки как массивы

Bizdelnick писал(а):
25.07.2016 12:33
Можно облегчить её, если задавать не адрес сети с маской, а диапазон адресов.

Не получится, потому что предполагается использовать скрипт в различных сетях, которые задаются именно как сеть/маска, причём маска не всегда кратна 8.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как освоить програмирование на bash

Сообщение Bizdelnick »

sunny1983 писал(а):
25.07.2016 13:01
Мне казалось, что в bash вообще нет такого понятия как строковые массивы

Это в POSIX shell их нет, а в bash есть:
http://wiki.bash-hackers.org/syntax/arrays
Ну то есть понятия строкового массива, по сути, нет, потому как нет никаких других массивов и переменных кроме строковых.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Goodvin
Ведущий рубрики
Сообщения: 4333
Статус: ⚝⚠⚒⚑⚖☭☞☣☤&

Re: Как освоить програмирование на bash

Сообщение Goodvin »

sunny1983 писал(а):
25.07.2016 12:49
SLEDopit писал(а):
25.07.2016 12:08
Но ведь есть expect. Как раз для подобных случаев. Зачем так извращаться с wine? :)

Затем, что The Dude в сети был внедрён до меня и меня это устраивает. До меня правда на всех рабочих станциях винда стояла. Я только хочу автоматизировать процесс управления свитчами, не вбивать ip-адрес в терминале, а кликать по карте, под виндой это работает - там просто PuTTY запускается с автовходом. если кто-нибудь мне объяснил как expect к bash-скрипту прибить.

Что Вы подразумеваете под "The Dude в сети был внедрён"?
Все сетевые протоколы и все родные UNIX-овые сетевые/системные инструменты прекрасно будут работать без этого чудного ПО.

Оно имело смысл, когда "на всех рабочих станциях винда стояла".
Вы же, очевидно, пытаетесь что-то делать под Linux.
Не вижу смысла самому себе вставлять в колеса вот эти избыточные костыли.

Вы либо пересмотрите подход и применяемые инструменты, либо переформулируйте задачу более предметно.
Спасибо сказали:
Аватара пользователя
sunny1983
Сообщения: 357
ОС: GNU/Linux 4.x (Fedora, Debian)
Контактная информация:

Re: Как освоить програмирование на bash

Сообщение sunny1983 »

Goodvin
Дело в том, что у нас в сети используется более 260 управляемых коммутаторов D-Link и нам как воздух необходима какая-нибудь система мониторинга. То есть тут либо внедрять какую-нибудь более сложную систему: zabbix, nagios или cacti, либо городить костыли. Поскольку тема не о системах мониторинга, а о программировании на bash, я задачу сформулировал именно так.
Спасибо сказали:
Аватара пользователя
sunny1983
Сообщения: 357
ОС: GNU/Linux 4.x (Fedora, Debian)
Контактная информация:

Re: Как освоить програмирование на bash

Сообщение sunny1983 »

Так как собственно вставить expect в bash-код?
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как освоить програмирование на bash

Сообщение Bizdelnick »

Дался Вам этот expect...

sunny1983 писал(а):
25.07.2016 11:13

Код: Выделить всё

#!/bin/bash
/usr/bin/xfce4-terminal -x "/usr/bin/ssh $1"

ssh-сессия не открывается, окно эмулятора терминала появляется на экране и тут же изчезает, я не успеваю прочитать, что на него выводится. А как в этом скрипте реализовать ещё и автовход - вообще не знаю.

А запустить эту команду руками пробовали? Чтобы работало, надо или

Код: Выделить всё

xfce4-terminal -x ssh "$1"
или

Код: Выделить всё

xfce4-terminal -e "ssh '$1'"
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Ответить