Reputation: 444
My code as below,
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";
}
}
What I try to do is get a server name which is the keys of %srvs, which is (serv_1, serv2, etc.)
When I run the code, I received below error,
Can't use string ("1") as a HASH ref while "strict refs" in use at .pl line 260, <> line 1.
I also try different method which is call as array from the case control statement,
----
----
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";
}
}
This code can be process, however it list all the server name (which is all the keys of %srvs) in single flat line, I cannot divide the list using foreach.
Need assist since quite confuse with the passing method.
Upvotes: 1
Views: 194
Reputation: 66883
The assignment is in the scalar context in your sub stop
on the line
my $servs = @_;
so $servs
receives the number of elements of @_
, that is 1
in your code. Then the attempt to dereference that 1
with %{$servs}
draws the error.
Change it to my ($servs) = @_;
where the ()
results in the list context for =
∗
A few comments.
The hash with servers is likely to be used mostly via its reference. Then why not use a hashref, my $serv = { ... }
There is never a reason to quote a scalar, like "$option"
; just switch($option)
The &
in front of a sub is quite special; you mostly likely need main()
instead of &main
Second code sample has stop("@s");
, whereby @s
is interpolated inside ""
. So the sub receives a single string: array elements with spaces between them. You need stop(@s)
You seem to be using 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
∗ The my @args = @_;
serves the same purpose of course. Then process @args
suitably.
A commonly seen way to retrieve the first argument is also
sub fun {
my $first_arg = shift; # same as: shift @_;
...
}
The shift removes an element from the front of its argument (array), and returns it; by default it acts on @_
which you thus don't have to write.
This is often seen in object-oriented code, to get the object off of @_
so that @_
can then be worked with more easily. But it is also often used when @_
has a single argument, for convenience.
Upvotes: 2