我的任务是通过 snmp 从打印机读取错误代码。幸运的是,我有一个有效的 bash 脚本来指导我完成这个神秘的任务。我正在编写一些 python 来做一些与现有脚本不同的工作。现有的代码似乎可以工作,但它非常丑陋,我希望有一种更 Python 的方式来解析位。
首先,解释一下我对当前代码的阅读。snmpwalk
查询返回的错误代码hrPrinterDetectedErrorState
被编码为八位字节字符串,通常带有引号。所以引号与空格和换行符一起被剥离。错误代码最多可以有四个字节,但如果为零,通常会为第二对发送一个空字节,因此在这种情况下会添加一对零。然后将错误代码转换为十六进制。
现有的 bash 脚本:
parseErrorState()
{
setUpErrorCodes
# pull the error state w/o quotes
errorState=`snmpwalk -Oqvx -c public -v $snmpV $printerIP hrPrinterDetectedErrorState | grep -v "End of MIB" | tr -d '"'`
# remove spaces
errorCode=$(echo $errorState | tr -d [:space:])
errorString=""
# if we don't have two hex bytes, append a byte of zeros
if [[ ${#errorCode} == 2 ]]
then
errorCode=$errorCode"00"
fi
# do hex conversion
let errorCode=0x$errorCode
if (( $errorCode & $overduePreventMaint ))
then
errorString=$errorString"Overdue Preventative Maintenance; "
fi
if (( $errorCode & $inputTrayEmpty ))
then
errorString=$errorString"Input Tray Empty; "
fi
if (( $errorCode & $outputFull ))
then
errorString=$errorString"Output Full; "
fi
if (( $errorCode & $outputNearFull ))
then
... and about 12 more if-thens...
这一系列 if-thens 逐位比较 与errorCode
其中的每一个,并将相关字符串添加到输出中。
setUpErrorCodes()
{
lowPaper=32768
noPaper=16384
lowToner=8192
noToner=4096
doorOpen=2048
jammed=1024
offline=512
serviceRequested=256
inputTrayMissing=128
outputTrayMissing=64
markerSupplyMissing=32
outputNearFull=16
outputFull=8
inputTrayEmpty=4
overduePreventMaint=2
}
我的 python 版本subprocess
用于snmpwalk
和或多或少地像上面那样进行格式化。然后:
# A dictionary of the errors and bit places
errors = {
16: "low paper",
15: "no paper",
...etc
# a still very ugly bit parse starting with a hex str like '2A00':
b = bin(int(hexstr, 16))[2:] # hex to int, int to bin, cut off the '0b'
binstr = str(b)
length = len(binstr)
indices = []
for i, '1' in enumerate(binstr):
# find negative index of all '1's and multiply by -1
# a hack to get around the binary string not containing leading zeros
indices.append((i-length)*-1)
然后只需将索引与错误字典进行比较,就完成了。
无论如何,非常丑陋,可能效率很低。什么是更python-y,高级,可读的方式来完成同样的事情?