URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9578
[ Назад ]

Исходное сообщение
"shell, perl arp запрос по ssh"

Отправлено guseniza , 12-Ноя-12 22:07 
Всем привет.
В скриптописании практически полный нуль.
Хотел бы попросить помощи знающих.
Есть скрипт, который собирает мак адреса на сетевом оборудовании.
После того, как он собрал, он в качестве параметра передает мак скрипту ssh_arp.sh,
который в свою очередь смотрит в arp табл серверов и находит соответствующий маку ip адрес.
Казалось бы, что может быть проще:)

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

#!/bin/bash

mac=$1

serv=(10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4)
for ((i=0; i<=4; i++))
do
    rez=$(ssh vasya@${serv[$i]} "arp -a | grep $mac")

    ip=$(echo $rez |sed 's/(//;s/)//'| awk '{print $2}')
    mac_cl=$(echo $rez |sed 's/(//;s/)//'| awk '{print $4}')
        
        if [ -n "$rez" ]; then     
        echo "$ip  $mac_cl"
        fi
    
done

т.е он получает параметром мак и ищет его на каждом сервере поочереди.
выполняется крайне долго...
Написал аналогичный на скрипт perl, в надежде на ускорение процесса:

#!/usr/bin/perl -w

#$ARGV[0] mac адрес
use Net::OpenSSH;

@vpnserv=("10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4");

for ($i=0; $i<=4; $i++)
{
    my $user = 'vasya';
    my $ssh = Net::OpenSSH->new(host => $serv[$i], user => $user, port => 22);
    $ssh->error and die "SSH connection failed: " . $ssh->error;

    my $rv = $ssh->system("arp -a | grep $ARGV[0]");

    if ($? != 0) {
    print "Данные отсутсвуют";
    }

}
В сравнении с bash скриптом perl овый выполняется с такой же скоростью.

Скрипты явно не заслуживают похвал :), но я только начал...
В общем прошу помощи либо в оптимизации данного решения, либо предложите другое решение, которое будет работать быстрее моего.

По поводу того, насколько медленно выполняется... поиск 40 маков занимает порядка 7 минут. Т.к. маки могут быть на разных серверах.


Содержание

Сообщения в этом обсуждении
"shell, perl arp запрос по ssh"
Отправлено hizel , 12-Ноя-12 22:20 
>  my $rv = $ssh->system("arp -a | grep $ARGV[0]");
>  if ($? != 0) {
>  print "Данные отсутсвуют";
>  }

ну правильно, в документации так и написано: "Returns true on sucess, undef otherwise."


"shell, perl arp запрос по ssh"
Отправлено guseniza , 12-Ноя-12 22:25 
>>  my $rv = $ssh->system("arp -a | grep $ARGV[0]");
>>  if ($? != 0) {
>>  print "Данные отсутсвуют";
>>  }
> ну правильно, в документации так и написано: "Returns true on sucess, undef
> otherwise."

на это не обращ внимания. Код работает. Получаю необходимый мне результат.
Меня интересует либо как ускорить процесс поиска маков, либо предложение другого метода поиска
>>  if ($? != 0) {
>>  print "Данные отсутсвуют";
>>  }

Эта часть, вообще, для себя любимого :) для наглядности. Можете ее выкинуть:)


"shell, perl arp запрос по ssh"
Отправлено hizel , 12-Ноя-12 22:29 
> на это не обращ внимания. Код работает. Получаю необходимый мне результат.
> Меня интересует либо как ускорить процесс поиска маков, либо предложение другого метода
> поиска

оу, ну запускайте параллельно, будет быстрее.


"shell, perl arp запрос по ssh"
Отправлено guseniza , 12-Ноя-12 22:41 
>> на это не обращ внимания. Код работает. Получаю необходимый мне результат.
>> Меня интересует либо как ускорить процесс поиска маков, либо предложение другого метода
>> поиска
> оу, ну запускайте параллельно, будет быстрее.

Это, конечно, вариант, но какой-то костыльный:))
Хотя, вероятно, его и придется использовать


"shell, perl arp запрос по ssh"
Отправлено Etch , 13-Ноя-12 03:36 
> По поводу того, насколько медленно выполняется... поиск 40 маков занимает порядка 7
> минут. Т.к. маки могут быть на разных серверах.

А зачем вы по одному МАКу проверяете, если их у вас 40? Проверяйте сразу все в одной команде.


"shell, perl arp запрос по ssh"
Отправлено Etch , 13-Ноя-12 03:58 
т.е. что-то вроде:

my $macs = join("|", @ARGV);

my $rv = $ssh->system("arp -a | grep -E \"$macs\"");

и при запуске все MAC-и передавать через командную строку.


"shell, perl arp запрос по ssh"
Отправлено meantraitor , 13-Ноя-12 12:10 
> Всем привет.
> В скриптописании практически полный нуль.
> Хотел бы попросить помощи знающих.
> Есть скрипт, который собирает мак адреса на сетевом оборудовании.
> После того, как он собрал, он в качестве параметра передает мак скрипту
> ssh_arp.sh,
> который в свою очередь смотрит в arp табл серверов и находит соответствующий
> маку ip адрес.
> Казалось бы, что может быть проще:)

Один раз собрать со всех серверов arp таблицы (arp -a), собрать в хэш-таблицу
а потом просто выдавать $ip{$mac}

Если диапазон ip-шников заранее известен и небольшой, можно их просто пропинговать, а
потом сказать arp -a

На худой конец, break в цикле поставить, если адрес найден


"shell, perl arp запрос по ssh"
Отправлено guseniza , 13-Ноя-12 14:16 
>[оверквотинг удален]
>> ssh_arp.sh,
>> который в свою очередь смотрит в arp табл серверов и находит соответствующий
>> маку ip адрес.
>> Казалось бы, что может быть проще:)
> Один раз собрать со всех серверов arp таблицы (arp -a), собрать в
> хэш-таблицу
>  а потом просто выдавать $ip{$mac}
> Если диапазон ip-шников заранее известен и небольшой, можно их просто пропинговать, а
> потом сказать arp -a
> На худой конец, break в цикле поставить, если адрес найден

Примерно так и сделал. По крону собираю arp табл с серверов в файлы.
"arp -a -n"  значительно быстрее отрабатывает, чем "arp -a".
А потом просто ищу МАК в файле.
Маков очень много, поэтому пинговать не вариант. Работает на 2 порядка быстрее :) Всем спасибо за советы:))


"shell, perl arp п╥п╟п©я─п╬я│ п©п╬ ssh"
Отправлено Salvador Fandi241o , 13-Ноя-12 15:05 
#! / Usr / bin / perl-w

# $ARGV[0] mac address
use Net::OpenSSH::Parallel;

@vpnserv = ("10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4");

my $p = Net::OpenSSH::Paralllel->new;

$p->add_host($_) for @vpnserv;
$p->all(cmd => "arp -a | grep $ARGV[0]");
$p->run;

for my $vpnserv (@vpnserv) {
  if ($p->get_error($vpnserv)) {
    print "MAC $ARGV[0] not found on $vpnserv\n"
  }
}


"shell, perl arp п╥п╟п©я─п╬я│ п©п╬ ssh"
Отправлено guseniza , 13-Ноя-12 21:31 
>[оверквотинг удален]
> @vpnserv = ("10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4");
> my $p = Net::OpenSSH::Paralllel->new;
> $p->add_host($_) for @vpnserv;
> $p->all(cmd => "arp -a | grep $ARGV[0]");
> $p->run;
> for my $vpnserv (@vpnserv) {
>   if ($p->get_error($vpnserv)) {
>     print "MAC $ARGV[0] not found on $vpnserv\n"
>   }
> }

вот спасибо, добрый человек:)))