Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > цикл с использованием Net::SSH::Perl


Автор: angeloflight 29.11.2009, 17:49
здраствуйте. возникла проблема при создании цикла с использованием net::ssh::perl. 

есть список шеллов локальной сети, вида
user:pass:host

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

Цитата

.......
#@uniq - массив из строк вида user:pass:host
foreach $str1 (@uniq) {
chop $str1;
@tmp=split(/:/,$str1);
$user=$tmp[0];
$pass=$tmp[1];
$host=$tmp[2];

$ssh = Net::SSH::Perl->new (
$host,
protocol => 2,
debug    => 1,
);
$ssh->login($user, $pass);
($out, $err, $exit) = $ssh->cmd($cmd);
}

 

но столкнулся со следующей проблемой, если один из компьютеров локальной сети завис или на перезагрузке, скрипт заканчивает свою работу не закончив цикл с ошибкой "Connection refused.....".  Как сделать так, чтобы после неудачного подключения скрипт не заканчивал цикл?

Автор: Pfailed 29.11.2009, 17:59
Видимо там происходит die(). Заключите этот блок в eval{};

Автор: angeloflight 29.11.2009, 18:16
спасибо вроде помогло)

Автор: angeloflight 29.11.2009, 18:51
все работает, но возникла новая проблема - не выполняется команда, пишет только версию ssh "Remote protocol version 2.0, remote software version OpenSSH_4.3p2 Debian-8..", а потом переходит к след подключению

Цитата

...............
$cmd="who";
foreach $str1 (@uniq) {
chop $str1;
@tmp=split(/:/,$str1);
$user=$tmp[0];
$pass=$tmp[1];
$host=$tmp[2];

eval{
$ssh = Net::SSH::Perl->new (
$host,
protocol => 2,
debug    => 2,
);
$ssh->login($user, $pass);
($out, $err, $exit) = $ssh->cmd($cmd)};
print $out."\n".$err."\n".$exit."\n";
}

Автор: angeloflight 29.11.2009, 20:42
проблема решена, путем установки доп библиотек

Автор: dmitryk1 30.11.2009, 07:10
подробнее можно список библиотек и вообще. 
результирующий работающий код?

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

Автор: angeloflight 9.12.2009, 12:51
все вобщем было хорошо, но возникла проблема, которую пытался решить сам - но так и не получилось. Скрипт подключается, выполняет команды, но переодически выдает ошибки и на n-ой стадии цикла заканчивает свою работу.  smile 

вот пример ошибок, которые переодически выводятся при запуске с ключем -W

Цитата

Use of uninitialized value in substitution (s///) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 264.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 265.
Use of uninitialized value in concatenation (.) or string at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 267.
Use of uninitialized value in concatenation (.) or string at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 267.
Use of uninitialized value in concatenation (.) or string at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 267.
Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 271.
Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 271.
Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 293.
Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 49.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 84.
Use of uninitialized value in concatenation (.) or string at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 90.
Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl/Packet.pm line 70.
Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.8.9/Net/SSH/Perl.pm line 333.
Use of uninitialized value in concatenation (.) or string at 1.pl line 40.


Библиотеки пересобирал кучу раз, в них мне кажется точно проблемы нет. погуглив пришел к выводу, что у меня в скрипте где то ошибка - но найти ее не могу (
Сильно не пинайте за кривой код, перл начал читать спецом, чтобы написать пару нужных скриптов.
вот пример скрипта:

Цитата

#!/usr/bin/perl

use Net::SSH::Perl ();

open(BASE,"< ssh.txt");
@ssh=<BASE>;
close(BASE);
@tmp=();
$cmd='w;last -n 10';

foreach $str1 (@ssh) {
$res=0;
$out=0;
$err=0; 
$exit=0;
chop $str1;
@tmp=split(/:/,$str1);
$user=$tmp[0];
$pass=$tmp[1];
$host=$tmp[2];
chomp $host;
chomp $user;
chomp $pass;

eval{
$ssh = Net::SSH::Perl->new ($host)};
$res = 1 if $@;
if($res==1)
{
open (BAD,">>bad.txt") || die "err\n";
print BAD  $str1."\n";
close (BAD);
}     
else{
eval{$ssh->login($user, $pass);
($out, $err, $exit) = $ssh->cmd($cmd)};
open (GOOD,">>good.txt") || die "err\n";
print GOOD  "login:pass---> ".$str1."\n".$out."\n"."--------------\n";
close (GOOD);
}
}


Автор: dmitryk1 10.12.2009, 05:36
Ну ругается, что у тебя переменная где-то пустая, а ты её юзаешь. 

пробуй проверять значения везде-везде. Есть или нет. После присваивания. У меня получалось такое когда я пустой результат запроса получал и пытался обработать smile

Автор: ginnie 10.12.2009, 14:59
angeloflight, если я правильно понимаю, скрипт тестирует работоспособность ssh-серверов. Похоже, что в списке есть сервера, где вместо ssh-сервера отвечает что-то другое. Т.к. Net::SSH::Perl не идеален, то Вы и получаете указанные выше предупреждения. Это всего лишь мое досужее рассуждение, т.к. код модуля Net::SSH::Perl я не смотрел.

Автор: amg 11.12.2009, 15:34
Раньше пробовал Net::SSH::Expect (показался крайне неудобным) и Net::SSH::Perl (трудно ставить и баговый). Недавно попробовал Net::OpenSSH. Производит хорошее впечатление. Рекомендую попробовать его.
Код
use Net::OpenSSH;

open(BASE,"< ssh.txt");
@ssh=<BASE>;
close(BASE);

$cmd='w;last -n 10';

foreach (@ssh) {
  my ($user,$pass,$host) = split /:/;
  print "\n$user\@$host\n";
  my $ssh = Net::OpenSSH->new($host,
                              user    => $user, 
                              passwd  => $pass,
                              timeout => 1,
                              );
  if ($ssh->error) {
    warn "$user\@$host: ". $ssh->error;
    next;
  }
  
  my $out = $ssh->capture($cmd);
  if ($ssh->error) {
    warn "'$cmd' on $user\@$host failed: ". $ssh->error;
    next;
  }
  print $out;
}


Автор: angeloflight 14.12.2009, 11:11
amg спасибо за ваш скрипт, поставил нужные библиотеки - но скрипт не работает, выдает след:

Код

Unsuccessful stat on filename containing newline at /usr/local/lib/perl5/site_perl/5.8.9/Net/OpenSSH.pm line 235.
Unsuccessful stat on filename containing newline at /usr/local/lib/perl5/site_perl/5.8.9/Net/OpenSSH.pm line 237.
Unsuccessful stat on filename containing newline at /usr/local/lib/perl5/site_perl/5.8.9/Net/OpenSSH.pm line 564.
ssh: illegal option -- M
Usage: ssh [options] host [command]
Options:
  -l user     Log in using this user name.
  -n          Redirect input from /dev/null.
  -F config   Config file (default: ~/.ssh/config).
  -A          Enable authentication agent forwarding.
  -a          Disable authentication agent forwarding (default).
  -X          Enable X11 connection forwarding.
  -x          Disable X11 connection forwarding (default).
  -i file     Identity for public key authentication (default: ~/.ssh/identity)
  -t          Tty; allocate a tty even if command is given.
  -T          Do not allocate a tty.
  -v          Verbose; display verbose debugging messages.
              Multiple -v increases verbosity.
  -V          Display version number only.
  -q          Quiet; don't display any warning messages.
  -f          Fork into background after authentication.
  -e char     Set escape character; ``none'' = disable (default: ~).
  -c cipher   Select encryption algorithm
  -m macs     Specify MAC algorithms for protocol version 2.
  -p port     Connect to this port.  Server must be on the same port.
  -L listen-port:host:port   Forward local port to remote address
  -R listen-port:host:port   Forward remote port to local address
              These cause ssh to listen for connections on a port, and
              forward them to the other side by connecting to host:port.
  -D port     Enable dynamic application-level port forwarding.
  -C          Enable compression.
  -N          Do not execute a shell or command.
  -g          Allow remote hosts to connect to forwarded ports.
  -1          Force protocol version 1.
  -2          Force protocol version 2.
  -4          Use IPv4 only.
  -6          Use IPv6 only.
  -o 'option' Process the option as if it was read from a configuration file.
  -s          Invoke command (mandatory) as SSH2 subsystem.
  -b addr     Local IP address.
Unsuccessful stat on filename containing newline at /usr/local/lib/perl5/site_perl/5.8.9/Net/OpenSSH.pm line 564.
[email protected]
: host failed


Автор: amg 14.12.2009, 11:21
Наверное, нужно было
Код
foreach (@ssh) {
  chomp;
  ...

Автор: angeloflight 14.12.2009, 11:52
тоже не помогло, ssh ругается на непонятный ключь "M". но я не могу понять откуда он берется.

Код

ssh: illegal option -- M


Автор: amg 14.12.2009, 12:19
Цитата(angeloflight @  14.12.2009,  11:52 Найти цитируемый пост)
тоже не помогло, ssh ругается на непонятный ключь "M". но я не могу понять откуда он берется.
Я вовсе не уверен, но подозрение есть. Попробуйте заменить 
chomp на s/\r?\n?$//

Автор: angeloflight 14.12.2009, 17:09
amg, спасибо за вашу помощь. проблема была не в коде, оказалось, что Net::OpenSSH не работает с openssh версиями младше 4. после перестановки, все заработало.  smile 

Автор: angeloflight 14.12.2009, 18:45
 smile 
к сожаление все заработало но появилась новая трабла, если адреса сервера нет в /.ssh/know_hosts - команда не выполняется и сервер помечается как неработающий.  Net::SSH::Perl заносит сервера в know_hosts. нельзя ли тут как то это организовать?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)