将哈希传递给子程序在 perl 中出错

Pass hash to subroutine comes to error in perl

我的代码如下,

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

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

Can't use string ("1") as a HASH ref while "strict refs" in use at .pl line 260, <> line 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 划分列表。

需要帮助,因为对传递方法很困惑。

赋值在你的sub stop

的标量上下文中
my $servs = @_;

所以$servs接收到@_的元素个数,也就是你代码中的1。然后尝试用 %{$servs} 取消引用 1 会引发错误。

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

的列表上下文

一些评论。

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

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

  • sub前面的&比较特别;您很可能需要 main() 而不是 &main

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

您似乎在使用 Switch module. It is a rather non-trivial source filter; surely there are other ways to do what you need. The feature switch is experimental, too. See Switch Statements in perlsyn


当然,my @args = @_; 的目的相同。然后适当处理@args

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

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

shift从它的参数(数组)前面移除一个元素,returns它;默认情况下,它作用于 @_ ,因此您不必编写。

这经常出现在面向对象的代码中,从 @_ 中取出对象,以便 @_ 可以更容易地使用。但为了方便起见,它也经常在 @_ 有一个参数时使用。