2015-10-28 8 views
1

Прошло некоторое время с тех пор, как я использовал perl, и я пытаюсь распечатать список файлов на SFTP-сервере.Perl чтение файлов с сервера SFTP

Это мой Perl скрипт -

#! /usr/bin/env perl 
use strict; 
use warnings; 
use feature qw(say); 
use autodie; 

use Net::SFTP::Foreign; 

# US Server Configuration 
use constant { 
    HOST   => "Server_Name", 
    REMOTE_DIR  => "\\", 
    LOCAL_DIR  => "sample/local", 
    PORT   => "3235", 
    USER_NAME  => "name", 
    PASSWORD  => "password", 
    BACKEND   => "Net_SSH2", 
    DEBUG   => "0", 
}; 

my $stfp = Net::SFTP::Foreign->new (
    HOST, 
    backend   => BACKEND, 
    timeout   => 240, 
    user   => USER_NAME, 
    password  => PASSWORD, 
    port   => PORT, 
    autodie   => 1, 
); 

# 
# List remote directory contents 
# 
my $remotefiles; 
$remotefiles = $stfp->ls(REMOTE_DIR); 

# 
# Loop through remote files and print each filename 
# 
foreach ($remotefiles){ 
    my $file = $_; 
    my $filename = $file->{filename}; 
    if($filename ne "." && $filename ne ".."){ 
     print"the filename is $filename"; 
    } 
} 

$stfp->disconnect; 

Я получаю следующее сообщение об ошибке - не ссылка HASH на этой линии -> мой $ имя_файла = $ файл -> {имя_файла};

Не знаете, в чем проблема или как это исправить.

ответ

3

Here's the documentation для сети :: SFTP :: Foreign. Это то, что он говорит о методе ls():

Возвращает ссылку на список записей. Каждая запись является ссылкой на хэш с тремя ключами: filename, имя записи ; longname, запись в длинном списке, таком как ls -l; и a, а Net::SFTP::Foreign::Attributes объекта, содержащий файл ATIME, время изменение, разрешение и размер

Итак, когда вы вызываете этот метод:

$remotefiles = $stfp->ls(REMOTE_DIR); 

Что вы получаете обратно ссылка на массив. Когда вы пытаетесь выполнить итерацию по этому массиву:

foreach ($remotefiles) 

Вы не занимаетесь тем, что, по вашему мнению, делаете. Вы повторяете список с одним элементом, который является ссылкой на массив. Итак, $file получает ссылку на массив, а не хеш-ссылку, которую вы ищете.

Итак, как это исправить? Ну, это достаточно просто. Вам нужно разделить $remotefiles, который превратит его в массив (а не ссылку на массив).

# Just add a '@' to dereference the reference and 
# get to the underlying array 
foreach (@$remotefiles) 

Теперь, каждый раз вокруг петли, $_ (и, следовательно, $file) будет содержать одну из ссылок хэш, описанных в моей цитате, и все будет работать, как вы ожидаете.

Важным уроком для изучения здесь является то, что вам нужно прочитать и понять документацию для используемого кода. Или, по крайней мере, вам нужно лучше копировать код из примеров. Пример ls() явно использует синтаксис разыменования.

my $ls = $sftp->ls('/home/foo') 
    or die "unable to retrieve directory: ".$sftp->error; 

print "$_->{filename}\n" for (@$ls); 
-1

$ filenane - ссылка на массив. Разверните переменную, чтобы получить ссылку на референт. См. Perlreftut для деталей. Это легко, когда вы это понимаете, но делать это в первый раз может быть немного больно.

+0

'$ filename' не является ссылкой на массив. '$ filename' никогда не получает значения. '$ remotefiles' - это ссылка на массив (и, следовательно, это' $ _' и '$ file'). –