我使用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参考 - >我的$ filename = $ file-> {filename};
不确定问题是什么或如何解决。
答案 0 :(得分:3)
Here's the documentation。这就是它对ls()
方法的说法:
返回对条目列表的引用。每个条目都是 引用具有三个键的哈希:
filename
,其名称 条目;longname
," long"中的一个条目列出像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);
答案 1 :(得分:-1)
$ filenane是一个数组引用。取消引用变量以获取referant。有关详细信息,请参阅perlreftut。当你掌握它时很容易,但第一次这样做可能会有点痛苦。