如何获取Net :: OpenSSH-> scp_get()方法复制的文件列表

时间:2012-12-11 11:13:26

标签: perl scp openssh

我想将远程机器的目录复制到本地。为此,我使用的是Net :: OpenSSH perl模块。它工作正常,文件也被复制到我的本地机器。但我想获取复制的文件列表。如何获取文件列表。

我不想使用Net :: SCP。

use Net::OpenSSH;
use Data::Dumper;

my $host='1.1.1.1';
my $credentials={username => 'root', password =>'abc123'};

my $ssh_obj = Net::OpenSSH->new(
                $host,
                user     => $credentials->{username},
                password => $credentials->{password},

            );
ooen $fh, ">/tmp/abc_scp" or die "$!";
my $opts={recursive => 1, glob => 1, timeout => 100, quiet => 1,stderr_to_stdout => 1,stdout_fh => $fh};
my $op=$ssh_obj->scp_get($opts, "/home/ABC", "/tmp/");

2 个答案:

答案 0 :(得分:1)

Net :: OpenSSH scp方法不允许这样做,但还有其他方法:

  • 使用tar

    $ssh->system({stdout_file => '| (cd /tmp/ && tar xvzf - ) 2>tar.log'},
                 '(cd /tmp/ABC && tar czf - .)');
    

    然后您必须阅读tar.log以获取复制的文件列表。

  • 通过Net :: OpenSSH + Net::SFTP::Foreign(或只是Net :: SFTP :: Foreign)使用SFTP:

    # untested!
    my $ssh = Net::OpenSSH->new(...);
    my $sftp = $ssh->sftp;
    
    my @log;
    $sftp->rget("/home/ABC", "/tmp",
                wanted => sub { push @log, $_[1]->{filenane} },
                on_error => sub { push @log if $_[1]->{filename} eq $log[-1] });
    
  • 使用可以在Net :: OpenSSH上运行的development version Net::SSH::Any

    my $ssh = Net::SSH::Any->new($host, ..., backend => 'Net::OpenSSH');
    my @log;
    $ssh->scp_get({recursive => 1, action_log => \@log}, "/home/ABC", "/tmp");
    

    Net :: OpenSSH本身并没有实现SCP协议,而是使用OpenSSH scp二进制文件,遗憾的是它不会返回复制的文件列表。 Net :: SSH :: Any有自己用Perl编写的SCP实现,所以可以做更多的事情。最终,一旦在Net :: SSH :: Any上的SCP实现成熟,我可能会将其反向移植到Net :: OpenSSH。

答案 1 :(得分:0)

您应该考虑仅使用rsync和无密码基于密钥的ssh,而只需从Perl调用它。它将为您带来以下好处:

  • 第二次和进一步尝试的同步时间非常快。它甚至会重启大量文件的部分下载。
  • 不是很依赖于Perl,或者它有时会出现奇怪的模块行为(不要误会我的意思 - 我喜欢Perl,但一切都有它的位置)。
  • 您可以执行递归同步并删除旧的本地文件:

    rsync -av --delete --progress --partial --stats \
          user@host:/src/dir/ dst/dir/
    
  • 您将获得已同步文件的列表(使用选项-v - 详细信息)。
  • 您可以使用rsync选项--stats获取一些同步统计信息。
  • 您可以使用--bwlimit选项限制同步过程使用的网络带宽。
  • 你永远不应该在你的脚本中嵌入密码(特别是root!)。配置无密码ssh并更好地睡眠。 rsync将使用它。