1

自从我使用 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};

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

4

2 回答 2

4

这是Net::SFTP::Foreign 的文档。这就是它所说的ls()方法:

返回对条目列表的引用。每个条目都是对具有三个键的散列的引用:filename,条目的名称;longname,一个“长”列表中的条目,如 ls -l;和 a,一个Net::SFTP::Foreign::Attributes对象,包含文件 atime、mtime、权限和大小

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

$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);
于 2015-10-28T16:24:19.907 回答
-1

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

于 2015-10-28T15:47:08.893 回答