【问题标题】:Unable to do SCP on multiple machines using Perl's Net::SCP::Expect module无法使用 Perl 的 Net::SCP::Expect 模块在多台机器上执行 SCP
【发布时间】:2014-06-19 00:43:55
【问题描述】:

我正在尝试 SCP 从一台机器到多台机器。我有一个用于执行无密码身份验证的身份文件。我遇到了 Net::SCP::Expect 模块,它在一台机器上做得很好,但是当它继续将组件复制到另一台机器时,它失败了。

代码如下:

use strict;
use warnings;
use Cwd;
use File::Copy;
use Getopt::Long;
use Net::SSH::Perl;
use Net::SCP::Expect;

my ($war_name, $wrapper_name, $host, $user, $war_build_path, $war_full_path, $war_archive_path, $war_archive_host, $HOME, $scpe, @id_file);

usage() if ( @ARGV < 6 or
            !GetOptions(
                    'war_name:s' => \$war_name,
                    'war_path:s' => \$war_build_path,
                    'wrapper_name:s' => \$wrapper_name,
                    'host=s' => \$host,
                    'user=s' => \$user,
            )
        );


if ($war_name && $war_build_path && $host && $user) {
    printf "Initiating subroutine to copy war on remote machine...\n";
    &copy_war;
}


sub copy_war {
    $war_full_path = "/home/tom/slave/workspace/Rel_Build/rec_dist/$war_name";
    $war_archive_path = "/home/tom";
    $war_archive_host = "xx.xxx.xxx.xx";

    if ( -f $war_full_path ) {
        printf "Copying war: $war_name\n";
        printf "Target Machine: $host\n";
        printf "User: $user\n\n";

        $scpe = Net::SCP::Expect->new(
                                    identity_file => "/home/tom/.ssh/id_file",
                                    host => $host,
                                    user => $user,
        );

        $scpe->scp("$war_full_path", "$HOME") or die $scpe->{errstr};

        printf "War copied on deployment machine. Now moving on to next task of archiving the war...\n";

        $scpe = Net::SCP::Expect->new(
                                    identity_file => "/home/tom/.ssh/id_file",
                                    host => $war_archive_host,
                                    user => $user,
        );

        $scpe->scp("$war_full_path", "$war_archive_path") or die $scpe->{errstr};
        printf "War archived on master\n";
    } else {
        printf "War not found\n";
    }
}


输出:

正在启动子程序以在远程机器上复制战争...
复制战争:remote-web.war
目标机器:xx.xxx.xxx.xx
用户:汤姆

在 /home/tom/deploy.pl 第 59 行的字符串中使用未初始化的值 $HOME。
在部署机器上复制了战争。现在继续下一个任务,存档战争...
在 /home/tom/perl/5.18.2/lib/site_perl/5.18.2/Expect.pm 第 760 行。


我尝试围绕错误#阅读 Expect.pm 文件,但无法理解。它与早期的对象没有被释放有什么关系吗?我在 CPAN 页面上找不到此模块关闭连接的任何方法。

更新: 感谢 Len 的回复,但老实说,我并没有真正认真地看待它,因为文件被复制到所需的位置,即 $user 的主目录中。在我将其更改为 $ENV{'HOME'} 或 $ENV{HOME} 后,即使是第一个 SCP 现在也无法正常工作。现在我得到以下信息:

Initiating subroutine to copy war on remote machine...
Copying war: remote-web.war
Target Machine: xx.xxx.xxx.xx
User: tom

at /home/tom/perl/5.18.2/lib/site_perl/5.18.2/Expect.pm line 760.ar: Permission denied

【问题讨论】:

  • 我意识到自己犯了错误。为了简化解释,在第一个 SCP 中,我需要以用户 A 的身份运行 SCP,而在位于不同服务器上的第二个 SCP 中,我需要一个不同的用户。然而,在我的脚本中,我使用同一个用户 A 在两台机器上执行 SCP,这就是它不起作用的原因。

标签: perl perl-module scp


【解决方案1】:

使用Net::OpenSSH::Parallel

my $pssh = Net::OpenSSH::Parallel->new;
$pssh->add_host($_) for @hosts;
$pssh->push('*', scp_put => $war_full_path, '~/');
$pssh->run;

【讨论】:

  • 感谢您的建议萨尔瓦!顺便说一句,我意识到我在使用模块“Net::SCP::Expect”时犯的错误。问题已解决。为了简化解释,在第一个 SCP 中,我需要以用户 A 的身份运行 SCP,而在位于不同服务器上的第二个 SCP 中,我需要一个不同的用户。然而,在我的脚本中,我使用同一个用户 A 在两台机器上执行 SCP,这就是它不起作用的原因。
  • @Technext:是的,我是。
【解决方案2】:

假设您需要$HOME 环境变量,您想使用$ENV{HOME} 从 Perl 的 ENVironment 哈希中查找值。

【讨论】:

  • 请检查我上面原始帖子中的“更新”部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 2019-11-27
  • 1970-01-01
  • 2012-11-05
  • 2014-12-07
  • 2015-05-21
  • 2014-02-25
相关资源
最近更新 更多