在perl中的一个Net :: SFTP :: Foreign会话中上传多个文件

时间:2014-07-14 12:13:23

标签: perl

我正在尝试使用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($_,"$_");

}

3 个答案:

答案 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>