I am newbie in Perl programming and currently trying to use Net::OpenSSH module in my code. My code as below which the task is to run multiple commands in remote server:
foreach $s (@servers) {
my $ssh = Net::OpenSSH->new("$username\@$s", timeout=>30);
$ssh->error and die "Unable to connect: " . $ssh->error;
print "Connected to $s\n";
my $fh = $ssh->capture("df -k /home/ | tail -1") or die "Unable to run command\n";
my @df_arr = split(/\s+/, $fh);
print "$s: Disk space /home/ = $df_arr[3] \n";
my $fh1 = $ssh->capture("svmon -G -O unit=GB | grep memory") or die "Unable to run command\n";
my @sv_arr = split(/\s+/, $fh1);
print "$s: Free memory = $sv_arr[3] \n\n";
close $fh;
undef $ssh;
}
This code is not so nice since I plan to simplify and reduce a line as many as possible.
Are there any techniques or methods that I can use to simplify this code?
-
\$\begingroup\$ Why not use standard tools, such as SNMP, instead of writing your own hacks? \$\endgroup\$200_success– 200_success2017年08月31日 18:27:58 +00:00Commented Aug 31, 2017 at 18:27
-
\$\begingroup\$ SNMP is a hard to manage, but there are a slow of alternatives for this that have more history and ease of use like nagios, OMD, or munin. I'm assuming this question is just a learning exercise and not the beginnings of a new monitoring system. \$\endgroup\$chicks– chicks2017年08月31日 22:07:17 +00:00Commented Aug 31, 2017 at 22:07
-
\$\begingroup\$ This exact same question/code was posted here on September 6, 2017 12:28 UTC. Is it your code? \$\endgroup\$Mathieu Guindon– Mathieu Guindon2017年09月07日 13:49:01 +00:00Commented Sep 7, 2017 at 13:49
-
1\$\begingroup\$ @Mat'sMug Hi, Im not posting my code to that website...it seem someone post it there. \$\endgroup\$MrAZ– MrAZ2017年09月11日 09:04:25 +00:00Commented Sep 11, 2017 at 9:04
2 Answers 2
Looks good to me. Kudos for the "... or die" idiom. More informative output would be "unable to run df on $s" or "unable to run svmon on $s".
You don't have to do tail
or grep
on the far end, as a line of perl could do that. But it is a perfectly clean and sensible approach, which I advocate keeping.
If you wind up with many such monitoring commands, you may find it convenient to move the post-processing into perl commands that can be refactored out as utility functions.
-
\$\begingroup\$ I can only add that proper indentation and more verbose variable names would improve legibility. \$\endgroup\$simbabque– simbabque2017年09月22日 14:13:01 +00:00Commented Sep 22, 2017 at 14:13
You should add indentation inside the loop:
foreach $s (@servers) {
my $ssh = Net::OpenSSH->new("$username\@$s", timeout=>30);
Consider this line of code:
foreach $s (@servers) {
The variable name $s
is not too descriptive. It would be better as
$server
.
Also, it should be localized to the loop using the my
keyword.
Since foreach
is identical to for
, you can just shorten it to for
.
for my $server (@servers) {
It is great that you check success of the commands. As the other answer
mentioned, it would be better from the user perspective to generate
unique messages for the df
and svmon
commands.
You can also add the $ssh->error
output to those messages as you did when
you checked new()
.
Again, the variable name $fh
is not too descriptive, and that name is
often associated with open file handles.
It might be better as $output
.
You can also reuse $output
instead of creating another variable ($fh1
).
Since capture
does not return a file handle, there is no need to call close
on it. This line can be deleted:
close $fh;
Explore related questions
See similar questions with these tags.