You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python的PySnmp获取指定OID的值?遇异常返回问题

解决PySnmp获取指定OID值的异常问题

我来帮你搞定这个PySnmp的问题——你遇到的情况其实是因为用错了API方法,咱们一步步理清楚:

问题根源

你现在用的nextCmd方法,核心作用是从指定OID开始,按字典序遍历后续所有OID节点。哪怕你传入的是叶子OID,它也会尝试查找下一个字典序的OID,所以会返回一堆无关结果;而当你设置lexicographicMode=True后,如果这个叶子OID已经是字典序的最后一个节点,自然就没有后续结果返回了。

你的需求是「传入OID列表,仅获取对应的值」,这完全是getCmd方法的职责——它专门用于直接获取指定OID的数值,不会额外遍历其他节点。

解决方案:使用getCmd替代nextCmd

下面是一个完整的示例代码,演示如何传入OID列表并精准获取对应的值:

from pysnmp.hlapi import *

def get_snmp_values(community, ip, oid_list):
    errorIndication, errorStatus, errorIndex, varBinds = next(
        getCmd(SnmpEngine(),
               CommunityData(community),
               UdpTransportTarget((ip, 161)),
               ContextData(),
               *[ObjectType(ObjectIdentity(oid)) for oid in oid_list])
    )

    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print(f"{errorStatus.prettyPrint()} at {errorIndex and varBinds[int(errorIndex)-1][0] or '?'}")
    else:
        for varBind in varBinds:
            print(f"{varBind[0].prettyPrint()} = {varBind[1].prettyPrint()}")

# 示例调用
get_snmp_values("public", "192.168.1.1", [
    "1.3.6.1.2.1.1.1.0",  # sysDescr
    "1.3.6.1.2.1.1.3.0"   # sysUpTime
])

额外说明:如果一定要用nextCmd怎么办?

如果你因为某些场景必须用nextCmd,可以通过设置maxRows=1来限制只返回当前OID的下一个结果(不过对于叶子OID来说,这种方式不如getCmd直接)。代码示例如下:

from pysnmp.hlapi import *

def next_snmp_single_value(community, ip, oid):
    errorIndication, errorStatus, errorIndex, varBindTable = next(
        nextCmd(SnmpEngine(),
                CommunityData(community),
                UdpTransportTarget((ip, 161)),
                ContextData(),
                ObjectType(ObjectIdentity(oid)),
                maxRows=1)
    )

    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print(f"{errorStatus.prettyPrint()} at {errorIndex and varBindTable[-1][int(errorIndex)-1][0] or '?'}")
    else:
        for varBindRow in varBindTable:
            for varBind in varBindRow:
                print(f"{varBind[0].prettyPrint()} = {varBind[1].prettyPrint()}")

但再次强调,对于你的需求来说,getCmd是最贴合、最不容易出错的选择。

内容的提问来源于stack exchange,提问作者Nikhil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:49:40