Как открыть канал и вставить данные в цикл while? - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь направить команду ls | grep в канал, который во время зацикливания и передачи вывода в массив @output. Но, хотя цикл while не обеспечивает необходимый вывод, из-за которого код умрет с die "could not find the file $_[1] in $Source to $Destination \n" unless(@output);. Если я прокомментирую часть кода и продолжу, копирование из источника в место назначения не работает.

Вот часть моего кода:

    my $host ="$hash{Linux_Server_IP}";
    my $Uname = "$hash{Linux_Server_Username}";
    my $password ="$hash{Linux_Server_Password}";
    my $ssh2= Net::SSH2->new();

    $ssh2->connect($host)or die "Could not connect : $@ \n ";
    $ssh2->auth_password($Uname,$password) or die "Could not login : Reason : $@\n";
    $ssh2->blocking();
    our $chnl = $ssh2->channel();
    $chnl->shell();

print $chnl "ls | grep $_[1] \n";
my @output;
sleep(1);
while (<$chnl>){push @output,$_};
die "could not find the file $_[1] in $Source to $Destination \n" unless(@output);
print $chnl "cp $Source $Destination \n";

Ошибка в журнале:

не удалось найти файл ABC.csv в /data/Directory1/ABC.csv в /data/Directory2/ABC.csv

Я вручную проверил файл на сервере, и он существует. Пожалуйста, порекомендуйте.

1 Ответ

0 голосов
/ 26 января 2019

Цитирование Сеть :: SSH2 :: Канал

Также можно запустить удаленную оболочку (используя оболочки) и имитировать пользовательские команды печати взаимодействия с его поток stdin и чтение данных обратно из stdout и stderr. Но следует избегать такого подхода, если это возможно; говорить с оболочкой сложно и вообще ненадежно.

Более того, использование ls для определения, существует ли файл / каталог, является хрупким и ненадежным. Вместо этого вы должны использовать файловые тестовые операции, например

sub exec_remote($$) {
    my($ssh2, $cmd) = @_;

    # every exec() requires a new channel
    my $chan = $ssh2->channel()
        or $ssh2->die_with_error;

    # send command to remote
    $chan->exec($cmd)
        or $ssh2->die_with_error;

    # we're done from our side
    $chan->send_eof;

    # ignore command output
    while (<$chan>) {}

    # wait for remote command to complete and return its exit status
    return $chan->exit_status;
}

sub copy_remote_if_necessary($$$$) {
     my($ssh2, $source, $destination, $file) = @_;

     if (exec_remote($ssh2, "/usr/bin/test -f ${destination}/${file}") ne 0) {
         die "Copy failed!\n"
             unless (exec_remote($ssh2, "cp ${source}/${file} ${destination}/") ne 0);
     }
}

copy_remote_if_necessary($ssh2, '/data/Directory1', '/data/Directory2', 'ABC.csv');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...