传递哈希到子例程在perl中出现错误

时间:2017-09-15 05:15:34

标签: arrays perl hash pass-by-reference subroutine

我的代码如下,

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等)

当我运行代码时,我收到以下错误,

  

在使用“严格参考”时,不能使用字符串(“1”)作为HASH参考   .pl第260行,&lt;&gt;第1行。

我还尝试了不同的方法,它从case控制语句中调用为数组,

----
----
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来划分列表。

需要帮助,因为与传递方法相当混淆。

1 个答案:

答案 0 :(得分:2)

分配位于行{/ p>} sub stop的标量上下文中

my $servs = @_;

因此$servs会在代码中收到@_的元素数量,即1。然后尝试取消引用1%{$servs}的错误。

将其更改为my ($servs) = @_;,其中()会导致= *

的列表上下文

一些评论。

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

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

  • 潜艇前面的&非常特别;您最有可能需要main()而不是&main

  • 第二个代码示例包含stop("@s");@s内插""。所以sub接收一个字符串:数组元素,它们之间有空格。您需要stop(@s)

您似乎正在使用Switch模块。它是一个相当重要的源过滤器;当然还有其他方法可以满足您的需求。 feature switch也是实验性的。见Switch Statements in perlsyn

* my @args = @_;当然是出于同样的目的。然后适当地处理@args

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

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

shift从其参数(数组)的前面删除一个元素,并返回它;默认情况下,它会作用于@_,因此您无需编写。

这通常出现在面向对象的代码中,以使对象脱离@_,以便@_可以更轻松地处理。但是为方便起见,@_只有一个参数时也经常使用它。