私は、snmp を介してプリンターからエラー コードを読み取ることを任されています。幸いなことに、この不可解なタスクをガイドするための有効な bash スクリプトがあります。既存のスクリプトとは異なる作業を行うために、いくつかの python を書いています。既存のコードは機能しているように見えますが、非常に見栄えが悪く、ビットを解析するためのより python-y な方法を望んでいます。
まず、現在のコードの読み方を説明します。snmpwalk
クエリによって返されるエラー コードはhrPrinterDetectedErrorState
、多くの場合、引用符で囲まれたオクテット文字列としてエンコードされます。そのため、引用符は空白と改行とともに削除されます。エラー コードは最大 4 バイトですが、通常、2 番目のペアがゼロの場合はヌル バイトが送信されるため、その場合はゼロのペアが追加されます。次に、エラー コードが 16 進数に変換されます。
既存の 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-thes はビット単位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で高レベルで読みやすい方法は何ですか?