我正在尝试使用Net :: SFTP :: Foreign模块将一组文件上传到perl中的远程计算机。文件名存储在文本文件中。但是没有上传所有文件。只上传了一个文件。
#!/usr/local/roadm/bin/perl
# This is compiled with threading support
use strict;
use warnings;
use threads;
use threads::shared;
use Net::SFTP::Foreign;
my $count=0;
my %args = (
user => 'root',
password => 'Ht5h10N2',
more => '-v',
autodisconnect => 0
);
print "Starting main program\n";
open(fa ,"<file_list.txt");
my @con =<fa>;
close fa;
my $sftp = Net::SFTP::Foreign->new('hadoop-dev2', %args);
foreach (@con)
{
chomp $_;
$sftp->put($_,"$_");
}
答案 0 :(得分:2)
您永远不会检查各种操作的状态!您的初始构造函数创建$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
以查看它什么时候不起作用。
对于Perl中的各种文件命令,您可以使用autodie
pragma,这是一个可用于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".);
}
Theres没有错误我运行你的代码,但我仍然无法上传:(任何帮助将不胜感激
所以,你说$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";
}
}
}
}
答案 1 :(得分:1)
我敢打赌,问题在于你有file_list.txt
文件的完整路径,并且FTP服务器上不存在文件路径。请记住,FTP不会为您创建目录,因此如果您有
/etc/passwd
在file_list.txt
中,您最好有一个名为
/etc
在您的FTP服务器上。
答案 2 :(得分:0)
问题是,代码是在带有cygwin的windows上运行所以其中一个主要错误是有单个VTY资源的线程竞争和用于获取TIMED OUT的线程,所以我使用expect脚本解决了它/ p>