Search code examples
shellsnmp

Parsing a hex value with spaces, last two characters are dropped


I have a script that gets snmpv3 engineID's from devices. It's been working fine on both my dev servers and my uat server. I moved the code from one to the next by creating a tar file of all my snmp configuration files, including the script and extracted the tar to the next server and recycled the services. On each one the snmpv3 traps get written to the log file. Yesterday I moved it to production and no traps are logging. in diagnosing that, I noticed that my snmpget command is dropping the last two digits of the hex string.

My code:

if test $snmpget_RC -eq 0
    then
        read dc1 dc2 dc3 hex < <(snmpget -v3 -l authPriv -u $UserName -a SHA -A mypassword -x AES -X myauthphrase $myIP SNMP-FRAMEWORK-MIB::snmpEngineID.0)
        MyHex=`echo $hex |sed 's/[[:blank:]]//g'`
        echo 'createUser -e' $MyHex  $UserName' SHA mypassword AES myauthphrase' >>$snmpPath/$MyFile
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') $myIP is not reachable" >> $myLog
        RC=0
fi

Running snmpget from the CLI returns

SNMP-FRAMEWORK-MIB::snmpEngineID.0 = Hex-STRING: 80 00 92 C4 04 53 4E 2D 35 33 32 30 34 35 37 32

39

I modified the script to echo the hex when running it interactively.

Hex value for deviceFQDN is 00092C404534E2D3533323034353732

As you can see, the read command isn't seeing the 39. (which makes me wonder why traps are logged on the other 3 servers, but that's another rabbit hole).

How can I fix the read command so the entire hex is captured?


Solution

  • Your snmpget outputs two lines with the 39 on the second line, but shell read reads ONE line. I notice most of the value can be interpreted as ASCII 'SN-532045729' which looks like a serial number; if so, perhaps the 3 working servers have serial numbers at least one digit shorter so they fit on the first line.

    In bash or zsh you can use read -d '' ... to read both (or in general multiple) lines, and the subsequent echo $hex (unquoted!) will effectively convert the newline to a space (specifically, expanding unquoted $hex breaks into separate arguments at any IFS character which by default includes space tab or newline, then echo joins its arguments back together with space). Although in bash or zsh you don't need the echo-plus-sed at all, just use ${hex//[[:space:]]}

    dash gives an error for -d and ksh93 accepts it but seems to ignore it (at least in my Ubuntu). For a POSIX shell if your script doesn't need the positional arguments at this point you could use them:

    set -- $(snmpget ...) # breaks at IFS which by default includes space and newline
    shift 3 # $*/$@ now contains only the hex fields
    IFS=""; # then use "$*" (in quotes to prevent resplitting) in place of $myhex