您从不检查各种操作的状态!您的初始构造函数 created$sftp 工作了吗?你打开的那个文件真的打开了吗?该文件是否存在于远程系统上?
您必须始终检查 Perl 中命令的状态!
use strict;
use warnings;
use feature qw(say);
use File::Basename;
use threads;
use threads::shared;
use Net::SFTP::Foreign;
my %args = (
user => 'root',
password => 'Ht5h10N2',
more => '-v',
autodisconnect => 0
);
# Where is `%args` coming from?
my $sftp = Net::SFTP::Foreign->new('hadoop-dev2', %args); # Check whether succeeded or failed!
if ( $sftp->error ) {
die qq(Could not establish the SFTP connection);
}
say "Starting main program";
open my $fh, "<", "file_list.txt" # Check whether succeeded or failed!
or die qq(Could not open file "file_list.txt");
}
while ( my $file = <$fh> ) {
chomp $file;
$sftp->put( $file, $file ) ); # Check whether succeeded or failed!
if ( $sftp->error ) {
warn qq(Could not download file "$file");
my $remote_files_ref = $sftp->ls(); # Check whether succeeded or failed!
if ( $sftp->error ) {
warn qq(Cannot get stat or remote directory.);
}
else {
say qq(List of files in "$remote_dir":);
for my $remote_file ( @{ $remote_files_ref } ) {
say " $remote_file";
}
}
}
}
注意我检查我的open 是否工作,$sftp 的构造函数是否工作,以及每次我使用来自Net::SFTP::Foreign 的方法。例如,我无法下载不存在的文件。也许它不存在,因此我做一个$sftp->ls 看看它什么时候不起作用。
您可以使用autodie,它是一个pragma,用于Perl 中的各种文件命令,并且是您可以用于Net::SFTP::Foreign 的设置。 Autodie 很不错,因为它会在出现错误时自动终止您的程序,从而将 perl 变成更多基于异常的语言。这样,如果出现错误,而你没有发现它,你的程序就会死掉。
如果您不希望您的程序彻底失败,您可以使用eval 来测试某些东西是否有效:
$sftp->Net::SFTP::Foreign( yadda, yadda, { autodie => 1} ); #Autodie is now turned on:
eval { # Checks whether the file exists
$sftp->get( $file, $file );
}
if ( $@ ) {
warn qq(ERROR: File "$file" is not found!);
} else {
say qq(Downloaded "$file".);
}
回复
我运行你的代码没有错误,但我仍然无法上传:(任何帮助将不胜感激
那么,您是说$sftp->get 不会下载文件,但也不会设置$sftp->error?
在代码中有几个地方,我看到返回了 undef,但没有调用 sftp->_set_error。让我们看看$sftp->get 是返回true 还是undef。根据源代码,这就是它应该做的。如果它是 undef,我们会假设它失败了。
while ( my $file = <$fh> ) {
chomp $file;
if ( not $sftp->put( $file, $file ) ) { # Check whether succeeded or failed!
warn qq(Could not download file "$file");
my $remote_files_ref;
if ( $remote_files_ref = $sftp->ls() ) { # Check whether succeeded or failed!
warn qq(Cannot get stat or remote directory.);
}
else {
say qq(List of files in "$remote_dir":);
for my $remote_file ( @{ $remote_files_ref } ) {
say " $remote_file";
}
}
}
}