【问题标题】:To upload multiple files in one Net::SFTP::Foreign session in perl在 perl 中的一个 Net::SFTP::Foreign 会话中上传多个文件
【发布时间】:2014-07-14 12:13:22
【问题描述】:

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

}

【问题讨论】:

  • 检查函数调用的返回状态如何?还是在调试器下运行?
  • 我用调试器运行它。它只是说程序终止了使用 r 重新开始执行
  • 尝试使用n(下一个)命令单步执行,而不是r(运行)。
  • 是的,它按原样执行文件中的所有行,但它没有被传输到远程机器(最后一个文件除外)
  • 尝试使用p(打印)命令在foreach末尾打印$_

标签: perl


【解决方案1】:

您从不检查各种操作的状态!您的初始构造函数 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-&gt;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-&gt;get 不会下载文件,但也不会设置$sftp-&gt;error

在代码中有几个地方,我看到返回了 undef,但没有调用 sftp-&gt;_set_error。让我们看看$sftp-&gt;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";
            }
        }
    }
}

【讨论】:

  • 我运行你的代码没有错误,但我仍然无法上传:(任何帮助将不胜感激
  • 好吧,让我们忘记sftp-&gt;error。在 Net::SFTP::Foreign 的 sub get 中有几个地方在返回 undef 之前没有设置 error。请参阅我的回复附加到我的答案
  • 我收到此错误无法获取统计信息或远程目录。在 t1.pl 第 35 行, 第 1 行。但我已将“/root”作为远程目录?但问题出在哪里?
  • 如果您不能对目录执行ls,则您没有该目录的执行权限。如果您以root 身份连接到远程计算机,您的用户ID 可能不是0。当您以 root 身份远程连接时,大多数系统会给您一个虚假的用户 ID。这是一项安全功能。那么,谁拥有/root?该目录的权限是什么?是不是类似于drwx------?如果是这样,则您无权读取文件甚至列出目录内容。这就是为什么你必须检查你的方法的结果。尝试直接向系统发送sftp,看看会发生什么。
  • 看看 `STP::Net::Foreign 中的 verbosemore 选项。尝试与这些一起运行,看看您是否获得更多详细信息。
【解决方案2】:

我敢打赌,问题在于您的file_list.txt 中有一些文件的完整路径,并且这些文件的路径在 FTP 服务器上不存在。请记住,FTP 不会为您创建目录,所以如果您有

/etc/passwd

在您的file_list.txt 中,您最好有一个名为

的目录
/etc

在您的 FTP 服务器上。

【讨论】:

  • 嗨,马克,不,我没有 file_list.txt 的完整路径,它只有文件名,我将其上传到 /root 问题是我是否有 acc1-in acc4-in flex-然后只有本地机器上的 flex-in 被放入远程机器上,虽然本地机器上存在的 acc1-in 和 acc4-in 没有被上传
【解决方案3】:

问题是,代码是在带有 cygwin 的 Windows 上运行的,所以主要错误之一是单个 VTY 资源存在线程竞争,并且线程用于超时,所以我使用期望脚本解决了它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多