【问题标题】:Can't use an undefined value as a HASH reference不能使用未定义的值作为 HASH 引用
【发布时间】:2017-02-14 20:59:04
【问题描述】:

我正在尝试对 wlc 上的 AP 状态进行 snmpwalk。我对 perl 真的很陌生,所以请耐心等待,但我正在使用 this guide。我能够很好地获得 CPU 利用率,但这只是一个获取请求,因为这是步行。

我的输入:perl test.pl -H 10.192.54.30 -C public -O .1.3.6.1.4.1.14179.2.2.1.1.6.0 -w 20 -c 30

代码:

#!/bin/perl
use strict;
use warnings;
use Net::SNMP;
use Getopt::Long qw(:config no_ignore_case);


my $hostaddr = '';
my $community = '';
my $crit = '';
my $warn = '';
my $oid = '';

GetOptions(
        "host|H=s" => \$hostaddr,
        "community|C=s" => \$community,
        "crit|c:s" => \$crit,
        "warn|w:s" => \$warn,
        "oid|O=s" => \$oid);

print "$hostaddr $community $crit $warn $oid\n";

my ($session, $error) = Net::SNMP->session(
                        -hostname => "$hostaddr",
                        -community => "$community",
                        -timeout => "30",
                        -port => "161");

if (!defined($session)) {
        printf("ERROR: %s.\n", $error);
        exit 1;
}

my $response = $session->get_table( -baseoid => $oid );

if (! defined $response) {
    die "Failed to get OID '$oid': " . $session->error;
}

foreach my $key (keys %$response) {
    print "$key: $response->{$key}\n";
}

my $err = $session->error;
if ($err){
        return 1;
}
print "\n";
exit 0;

输出:

10.192.54.30 public 30 20  .1.3.6.1.4.1.14179.2.2.1.1.6.0
Can't use an undefined value as a HASH reference at test.pl line 26.

【问题讨论】:

  • get_request() 在您的代码中失败。 $response 对象因此是未定义的。您尝试访问未定义的值。打印 $err 以获取更多信息。
  • 我在第 29 行添加了 print $err 并得到了相同的输出。
  • 你确定吗? $session->error() 应该打印来自 get_request() 的错误。见:search.cpan.org/~dtown/Net-SNMP-v6.0.1/lib/Net/…
  • 你的代码有strictwarnings!而你的教程没有。那太棒了!即使你声称自己是 Perl 的新手,但你在做最关键的事情是正确的。干得好:)
  • 您可以使用 Data::Dumper 直接查看$sessionuse Data::Dumper; print Dumper $session;。这是一个对象,但它只会显示与之关联的数据。大多数时候,这是开始调试的最佳位置。请注意,use 语句位于顶部,但如果它只是用于调试并且您稍后将其取出,只需将其放在您需要的地方即可。这样您以后会记得将其删除。

标签: perl snmp nagios


【解决方案1】:

几个问题:

  • 你打错了$session->get_request。至少,您必须传递-varbindlist 选项和OID 的arrayref。请参阅documentation

  • get_request 出错时返回 undef,并且由于 undef 不是哈希引用,因此您不能取消引用它。在尝试使用 $response 执行某些操作之前,您必须检查错误。

  • 您不应该将$response 的内容复制到单独的哈希中来打印它们。

固定版本:

my $response = $session->get_request( -varbindlist => [$desc] );

if (! defined $response) {
    die "Failed to get OID '$desc': " . $session->error;
}

foreach my $key (keys %$response) {
    print "$key: $response->{$key}\n";
}

# Alternatively,
# use Data::Dumper; print Dumper $response;

【讨论】:

  • 这似乎解决了一个问题,但现在我得到“在错误索引 1 处收到 noSuchName(2) 错误状态”,但我可以使用 snmpwalk 很好地遍历 OID。
  • snmpwalk -c public 10.192.54.30 -v 1 .1.3.6.1.4.1.14179.2.2.1.1.6 iso.3.6.1.4.1.14179.2.2.1.1.6.176.170.119.98.152.208 =整数:1 iso.3.6.1.4.1.14179.2.2.1.1.6.176.170.119.204.244.0 = 整数:1 iso.3.6.1.4.1.14179.2.2.1.1.6.244.207.226.84.120.224 = 整数:1 iso .3.6.1.4.1.14179.2.2.1.1.6.244.207.226.133.180.16 = 整数:1 iso.3.6.1.4.1.14179.2.2.1.1.6.244.207.226.137.75.224 = 整数:1 iso.3.6.1.4 .1.14179.2.2.1.1.6.244.207.226.137.116.80 = 整数:1 iso.3.6.1.4.1.14179.2.2.1.1.6.244.207.226.137.117.144 = 整数:1
  • perl test.pl -H 10.192.54.30 -C public -O .1.3.6.1.4.1.14179.2.2.1.1.6 -w 20 -c 30 10.76.64.12 r350urc31 30 20 .1.3.6.1 .4.1.14179.2.2.1.1.6 未能获得 OID '.1.3.6.1.4.1.14179.2.2.1.1.6':在 test.pl 第 28 行的错误索引 1 处收到 noSuchName(2) 错误状态。
  • @red_eagle 要进行苹果对苹果的比较,您应该使用snmpget 而不是snmpwalk。我在您的 snmpwalk 输出中没有看到 OID .1.3.6.1.4.1.14179.2.2.1.1.6,所以我认为您的 SNMP 代理没有提供它。
  • 那个oid是第一部分。我明白你的意思,所以我试图用 get_next_request 设置一个 while 循环,只要定义了 $response 它就可以工作。真的,如果你想看看真正的目标是什么,我在bash 中写了它,但 Nagios/icinga 似乎更喜欢 perl。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多