简体   繁体   English

在一个Net :: SFTP :: Foreign会话中上载多个文件

[英]To upload multiple files in one Net::SFTP::Foreign session in perl

I am trying to upload a set of files to a remote machine in perl using Net::SFTP::Foreign module. 我正在尝试使用Net :: SFTP :: Foreign模块将一组文件上传到perl中的远程计算机。 The file names are stored in a text file .But all the files are not getting uploaded . 文件名存储在一个文本文件中。但是所有文件都没有上载。 Only one file is getting uploaded. 仅上传一个文件。

#!/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($_,"$_");

}

You never check the status of your various operations! 您永远不会检查各种操作的状态! Did your initial constructor creating $sftp work? 您最初创建$sftp构造函数是否起作用? Was that file you opened really opened? 您打开的那个文件真的打开了吗? Does that file exist on the remote system? 该文件在远程系统上是否存在?

You must always check the status of your commands in Perl! 您必须始终在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";
            }
        }
    }
}

Note I check whether my open worked, whether the constructor for $sftp worked, and every time I use a method from Net::SFTP::Foreign . 注意,我检查open是否有效, $sftp的构造函数是否有效,以及每次使用Net::SFTP::Foreign For example, I can't download a file that doesn't exist. 例如,我无法下载不存在的文件。 Maybe it doesn't exist, thus I do a $sftp->ls to see when it doesn't work. 也许它不存在,因此我执行$sftp->ls来查看它何时不起作用。

You can use autodie which is a pragma for various file commands in Perl, and is a setting you can use for Net::SFTP::Foreign . 您可以使用autodie这是一个编译用于在Perl各种文件的命令,并且是一个设置,您可以使用Net::SFTP::Foreign Autodie is nice because it kills your program automatically upon an error, thus turning perl into more of an exception based language. Autodie很不错,因为它会在出现错误时自动杀死程序,从而使perl成为更多基于异常的语言。 This way, if there's an error, and you don't catch it, your program dies. 这样,如果出现错误,而您没有发现它,则程序将死亡。

If you don't want you program to outright fail, you can use eval to test whether something worked or not: 如果您不希望程序彻底失败,则可以使用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".);
}

Reply 回复

Theres no error i ran your code, but i still cant upload :( Any help would be appreciated 没有错误,我运行了您的代码,但是我仍然无法上传:(任何帮助,我们将不胜感激

So, you're saying that $sftp->get doesn't download the file, but neither sets $sftp->error ? 因此,您是说$sftp->get不会下载文件,但都不会设置$sftp->error吗?

There are a few places in the code where I see that an undef is returned, but sftp->_set_error isn't be called. 我在代码中的一些地方看到返回了undef ,但是没有调用sftp->_set_error Let's just see if $sftp->get returns a true or undef . 让我们看看$sftp->get返回trueundef According to the source code, that's what it should be doing. 根据源代码,这就是应该做的。 If it's undef, we'll assume it failed. 如果是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";
            }
        }
    }
}

I'll bet that the problem is that you have some full paths to files in your file_list.txt and that the paths to the files do not exist on the FTP server. 我敢打赌,问题在于您的file_list.txt有一些文件的完整路径,并且FTP服务器上不存在这些文件的路径。 Remember that FTP doesn't create directories for you, so if you have 请记住,FTP不会为您创建目录,因此如果您有

/etc/passwd

in your file_list.txt , you better have a directory called 在您的file_list.txt ,最好有一个名为

/etc

on your FTP server. 在您的FTP服务器上。

问题是,该代码正在cygwin上在Windows上运行,因此主要错误之一是与单个VTY资源的线程竞争以及用于获取TIMED OUT的线程,因此我使用Expect脚本解决了该问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM