将散列传递给子例程在Perl中出错

arrays perl hash pass-by-reference subroutine

97 观看

1回复

97 作者的声誉

我的代码如下

my %srvs = (
    serv_1 => {
         agents => 'agent_path',
         ...
         ...
    },
    serv_2 => {
         <same like above>
    },
    serv_3 => {
          ...
    ........
    ........
    serv_8 => {
            ...
    },
);

        switch ("$option") {
                case 1  { print "Option 1 selected. \n"; &main; }
                case 2  { print "Option 2 selected. \n"; stop(\%srvs); }
                case 3  { print "Option 3 selected. \n"; start(\%srvs); }
                else    { print "Option are not valid. \n"; exit 0; }
        }

sub stop {
        my $servs = @_;

        foreach my $s_name (sort keys %{$servs}) {
                print "$s_name \n";             

                my $ssh = Net::OpenSSH->new("<user_id>\@$s_name", timeout=>30);
                $ssh->error and die "Unable to connect $s_name  --->  " . $ssh->error and print "\n";

                $ssh->pipe_in("perl /<path>/<script_name>.pl stop all") or die "Unable to run command.\n";
        }

}

我想做的是获取一个服务器名称,该名称是%srvs的键,即(serv_1,serv2等)

运行代码时,出现以下错误,

在.pl第260行,<>第1行使用“ strict refs”时,不能将字符串(“ 1”)用作HASH ref。

我还尝试了从案例控制语句中将其称为数组的其他方法,

----
----
case 2  { print "Option 2 selected. \n"; my @s = sort keys %srvs; stop("@s"); }
---
---
sub stop {

        my @servs = @_;

        foreach my $s_name (@serv) {
                print "$s_name \n";             

                my $ssh = Net::OpenSSH->new("<id_server>\@$s_name", timeout=>30);
                $ssh->error and die "Unable to connect $s_name  --->  " . $ssh->error and print "\n";

                $ssh->pipe_in("<path_name> <script_name>.pl stop all") or die "Unable to run command.\n";
        }
}

该代码可以被处理,但是它以单行形式列出了所有服务器名称(即%srvs的所有键),我无法使用foreach划分列表。

需要协助,因为与传递方法相当混乱。

作者: MrAZ 的来源 发布者: 2017 年 9 月 15 日

回应 1


2

40851 作者的声誉

决定

分配是在您sub stop在线的标量上下文中

my $servs = @_;

所以$servs接收的元素的数量@_,这是1在你的代码。然后尝试取消引用的是1%{$servs}绘制错误。

将其更改为my ($servs) = @_;()列表中的上下文结果= *

一些评论。

  • 服务器的哈希很可能主要通过其引用来使用。那为什么不使用hashrefmy $serv = { ... }

  • 从来没有理由引用标量,例如"$option";只是switch($option)

  • &在子面前的是比较特殊; 您最有可能需要main()而不是&main

  • 第二个代码样本具有stop("@s");,从而@s在内部进行插值""。因此,子接收一个字符串:数组元素之间有空格。你需要stop(@s)

您似乎正在使用Switch模块。这是一个相当重要的源过滤器;当然,还有其他方法可以满足您的需求。该功能开关是实验性的,太。请参阅perlsyn中的Switch语句


*   该my @args = @_;服务,当然同样的目的。然后@args适当处理。

检索第一个参数的常用方法也是

sub fun {
    my $first_arg = shift;  # same as: shift @_;
    ...
}

移位从其参数(数组)的开头删除元素,然后将其返回;默认情况下,它的作用@_是您不必编写。

这在面向对象的代码中很常见,它可以使对象脱离对象,@_从而@_可以更轻松地进行操作。但是@_,为了方便起见,在只有一个参数时也经常使用它。

作者: zdim 发布者: 2017 年 9 月 15 日
32x32