如何获取 Net::OpenSSH->scp_get() 方法复制的文件列表
Posted
技术标签:
【中文标题】如何获取 Net::OpenSSH->scp_get() 方法复制的文件列表【英文标题】:How to get a list of file copied by Net::OpenSSH->scp_get() method 【发布时间】:2012-11-28 22:34:48 【问题描述】:我想将一个目录从远程机器复制到本地。为此,我正在使用 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/");
【问题讨论】:
您的ooen
声明中有错字;)
如果您启用 'verbose=>1',它将打印发送的文件。不幸的是,您还必须筛选所有调试语句。
【参考方案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 之上运行的 Net::SSH::Any 的 development version:
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。
【讨论】:
【参考方案2】:您真的应该考虑只使用rsync
和无密码的基于密钥的 ssh,而只需从 Perl 调用它。它将为您带来以下好处:
您可以进行递归同步并删除旧的本地文件:
rsync -av --delete --progress --partial --stats \
user@host:/src/dir/ dst/dir/
您将获得同步文件列表(使用选项-v
- 详细)。
您可以使用 rsync 选项 --stats
获取一些同步统计信息。
您可以使用--bwlimit
选项限制同步进程使用的网络带宽。
您不应该将密码(尤其是 root!)嵌入到您的脚本中。配置无密码 ssh 并更好地睡眠。 rsync
将使用它。
【讨论】:
我不能使用你的建议,因为我不想使用系统调用。我的某些机器没有 rsync 命令。以上是关于如何获取 Net::OpenSSH->scp_get() 方法复制的文件列表的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 perl 和 Net::OpenSSH 在远程机器上启动后台进程?
Net::OpenSSH::Gateway->find_gateway 在设置 ControlPersist 选项时失败