简体   繁体   中英

pysnmp - ValueError: too many values to unpack (expected 4)

If I try something like this, I got

ValueError: too many values to unpack (expected 4)

Can someone explain why?

from pysnmp.hlapi import *

errorIndication, errorStatus, errorIndex, varBinds =  nextCmd(
    SnmpEngine(),
    CommunityData('public', mpModel=1),
    UdpTransportTarget(('giga-int-2', 161)),
    ContextData(),
    ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.1')),
   lexicographicMode=False
)
if errorIndication:
    print(errorIndication)
elif errorStatus:
    print('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
else:
    for v in varBinds:
        for name, val in v:
            print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))

The nextCmd() function (as well as other pysnmp functions) returns a single Python generator object which you should iterate over:

>>> from pysnmp.hlapi import *
>>> g = nextCmd(SnmpEngine(),
...             CommunityData('public'),
...             UdpTransportTarget(('demo.snmplabs.com', 161)),
...             ContextData(),
...             ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr')))
>>> next(g)
(None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')),
              DisplayString('SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m'))])

You can use this generator like any Python iterable, for example in a loop. Or, if you need to run just a single request/response, you can simply call next on it.

On each iteration pysnmp sends out a request (one or more depending of circumstances) asking for a single OID which is greater than the previous one. That way you "walk" the SNMP agent till you break out of the loop or exhaust OIDs on agent's side.

Your mistake here is that you are expecting pysnmp's nextCmd to run SNMP query immediately and return a value. Instead pysnmp gives you a generator-coroutine which you can use repeatedly to perform multiple queries (you can also .send() it OIDs to query).

Thanks for the answer. I rewrote the code. Now it's doing what I wanted. It just searches through the '1.3.6.1.2.1.31.1.1.1.x' tree.

from pysnmp.hlapi import *

for errorIndication, errorStatus, errorIndex, varBinds in  nextCmd(
    SnmpEngine(),
    CommunityData('public', mpModel=1),
    UdpTransportTarget(('giga-int-2', 161)),
    ContextData(),
    ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.1')),
    lexicographicMode=False
):
    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
    else:
        for v in varBinds:
            print(v.prettyPrint())

SNMPv2-SMI::mib-2.31.1.1.1.1.1 = sc0
SNMPv2-SMI::mib-2.31.1.1.1.1.2 = sl0
SNMPv2-SMI::mib-2.31.1.1.1.1.3 = sc1
SNMPv2-SMI::mib-2.31.1.1.1.1.5 = VLAN-1
SNMPv2-SMI::mib-2.31.1.1.1.1.6 = VLAN-1002
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM