如何通过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
相关产品推荐
相关产品推荐

