2015-04-22 3 views
0

У меня проблема с сетью :: SSH2 :: Channel. Я работаю над Oracle LINUX 2.6.39-400.214.5.el6uek.x86_64, используя perl-5.10.1-136.el6.x86_64.Проблемы с perl Net :: SSH2 :: channel

Удаленный сервер выполняет Debian 3.2.60-1 + deb7u3 x86_64.

Perl-код будет использоваться как функция внутри сценария bash. Прямо сейчас, это простой perlscript.

Я не очень опытен для программирования perl. До сих пор я только адаптировал существующие perlscripts.

С моим testcript я могу войти на удаленный сервер с помощью SSH2.

Тогда я могу выполнить одну и только одну команду, используя $chan->shell(<conmmand>); Вторая команда, похоже, сбой, даже если она будет успешно выполнена в качестве первой команды оболочки в скрипте. -> Говорят, что $chan->exec(); поддерживает только одну команду на канале, $chan->shell(); следует использовать несколько раз на одном канале. Закрытие канала с помощью $chan-->close; и повторное его открытие также не помогают. -> Как интерпретировать вывод $ssh2->error;?

Мой второй вопрос: что именно блокирует выполнение? И в чем разница между использованием блокировки на ssh-соединении (ssh->blocking();) и на канале ($chan->blocking(0);)? Я видел и то, и другое. Для меня не было эффекта, используя блокировку на канале или не используя его.

Наконец, я не знаю, как получить возвращаемое значение выполненной команды и как ее прочитать таким образом, что мне не нужно заранее знать ее длину. (Каталог/tmpp, который используется в testcript, не существует. Использование существующего каталога ничего не меняет. Мой вывод всегда совпадает с первыми 65 символами вывода uname -a Когда я установил bufleng =70, скрипт зависает. Вот, что-то, кажется, совершенно неправильно.

Любые предложения очень приветствуются. Спасибо за вашу поддержку.

Bye Ralf


мой сценарий выглядит следующим образом:

#!/usr/bin/perl 
 

 
    use warnings; 
 
    use strict; 
 
    use Net::SSH2; 
 
    use Data::Dumper; 
 

 
    # Handling options 
 
    my $host = shift; 
 
    my $user = shift; 
 
    my $passwd = shift; 
 
    my $command = shift; 
 
    my $destination = shift; 
 
    #my $source = $ARGV; 
 

 
    # Defining variables 
 
    my $LEC=""; 
 

 
    #my $scp_session=new Net::ssh2 (Errmode=>'return', 
 
    my $ssh2=Net::SSH2 -> new(); 
 
    $ssh2->debug(1); 
 
##print Dumper($ENV); 
 

 
    ### Connecting (10) 
 
    #die "can\'t connect to ${host}, Error 10" unless $ssh2->connect($host); 
 
    #print "Connected to ${host}\n"; 
 
    $ssh2->connect($host); 
 
    if ("$?"==0) { 
 
    print "Connected to ${host}\n"; 
 
    } else { 
 
    print "can\'t connect to ${host}, Error 10\n"; 
 
    #print $ssh2->error; 
 
    print "\n"; 
 
    } 
 

 
    ### Logging in (20) 
 
    #die "can't authenticate as ${user}" unless 
 
    #$ssh2->auth(username => '${user}',password => '${passwd}'); 
 
    $ssh2->auth_password(${user},${passwd}); 
 
    # print $ssh2->error; 
 
    # #print "\n"; 
 
    if ("$?"==0) { 
 
    print " Authenticated as ${user}\n"; 
 
    } else { 
 
    print $ssh2->error; 
 
    print " Authentication failed\n"; 
 
    exit 20 
 
    } 
 

 
print " ## step 0\n"; 
 

 
    ### workload (30) 
 
    my $chan = $ssh2->channel(); 
 
    print $ssh2->error; 
 
    print "\n ## step 2\n"; 
 
    #$chan->blocking(0); 
 
    # print $ssh2->error; 
 
    # print "\n ## step 3\n"; 
 
    #$chan->shell('set cli-parameters console pager disabled'); 
 
    # print $ssh2->error; 
 
    # print "\n ## step 4\n"; 
 
    # $chan->close; 
 
    # my $chan = $ssh2->channel(); 
 
    ### testing 
 
    $chan->shell('ls -la'); 
 
    print $ssh2->error; 
 
    print "\n ## step 5\n"; 
 
    my $buflen = 65; 
 
    my $buf1 = '0' x $buflen; 
 
    $chan->read($buf1, $buflen); 
 
    print $buf1,"\n"; 
 
    $chan1->shell(${command}); 
 
    print $ssh2->error; 
 
    print "\n ## step 6\n"; 
 
    #my $buflen = 70; 
 
    print $ssh2->error; 
 
    print "\n ## step 7\n"; 
 
    my $buf2 = '0' x $buflen; 
 
    print $ssh2->error; 
 
    print "\n ## step 8\n"; 
 
    $chan->read($LEC, $buflen); 
 
    print $ssh2->error; 
 
    print "\n ## step 9\n"; 
 
    print "${command}:\n", $buf1,"\n"; 
 
    print $ssh2->error; 
 
    print "\n ## step 10\n"; 
 
    $chan->shell('exit'); 
 
    print $ssh2->error; 
 
    print "\n ## step 11\n"; 
 

 

 
    ### Logging off and disconnecting (90) 
 
    $ssh2->disconnect($host); 
 
    #print $ssh2->error; 
 
    #print "\n"; 
 

 

 
    #($ssh2->auth_password($user,$passwd)) { 
 
     #print "\n Executing command...\n"; 
 
     my $cmd = "ls"; 
 
     #print " ==> Running $cmd\n";


Выход:

perl ./test2.perl ifbscdd root dcdiag "LEC=1 ; [ -d /tmp ] && LEC=9 ; export LEC ; return $LEC" 
 
Connected to ifbscdd 
 
    Authenticated as root 
 
    ## step 0 
 
libssh2_channel_open_ex(ss->session, pv_channel_type, len_channel_type, window_size, packet_size, ((void *)0) , 0) -> 0x1b89fc0 
 
0 
 
    ## step 2 
 
0 
 
    ## step 5 
 
Net::SSH2::Channel::read(size = 65, ext = 0) 
 
- read 65 bytes 
 
- read 65 total 
 
Linux ifbscdd 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u3 x86_64 
 

 
libssh2_channel_open_ex(ss->session, pv_channel_type, len_channel_type, window_size, packet_size, ((void *)0) , 0) -> 0x1ba6490 
 
0 
 
    ## step 6 
 
0 
 
    ## step 7 
 
0 
 
    ## step 8 
 
Net::SSH2::Channel::read(size = 65, ext = 0) 
 
- read 0 bytes 
 
- read 0 total 
 
0 
 
    ## step 9 
 
LEC=1 ; [ -d /tmp ] && LEC=9 ; export LEC ; return : 
 
Linux ifbscdd 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u3 x86_64 
 

 
0 
 
    ## step 10 
 
-1LIBSSH2_ERROR_SOCKET_NONEFailed waiting for channel success 
 
    ## step 11 
 
Net::SSH2::Channel::DESTROY 
 
Net::SSH2::Channel::DESTROY 
 
Net::SSH2::DESTROY object 0x1aa6230

ответ

0

Вы можете вызывать только shell один раз для каждого объекта канала.

Также обратите внимание, что метод shell не принимает никаких аргументов.Для того, чтобы выполнить команду, вы должны записать его на канал:

$channel->write("$cmd\n"); 

Или обычно, вместо этого, вы запрашиваете новый объект канала для каждой команды, которую требуется запустить, а затем вызвать его метод exec с командой, как Аргумент. В общем, говорить с оболочкой, как вы пытаетесь сделать, это плохая идея и довольно сложно сделать правильно.

В любом случае, поскольку вы работаете в среде Linux, вместо Net :: SSH2, который довольно примитивен и глючит, вы можете использовать Net::OpenSSH.