Perl 从 SFTP 服务器读取文件

Perl reading files from SFTP server

自从我使用 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 引用 -> my $filename = $file->{filename};

不确定问题是什么或如何解决。

$filenane 是一个数组引用。取消引用变量以获取引用。有关详细信息,请参阅 perlreftut。掌握了它很容易,但是第一次做可能会有点痛苦。

Here's the documentation Net::SFTP::Foreign。这就是它对 ls() 方法的描述:

Returns a reference to a list of entries. Every entry is a reference to a hash with three keys: filename, the name of the entry; longname, an entry in a "long" listing like ls -l; and a, a Net::SFTP::Foreign::Attributes object containing file atime, mtime,permissions and size

所以当你调用这个方法时:

$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);