我的任務是通過snmp從打印機讀取錯誤代碼。幸運的是,我有一個可用的bash腳本來指導我完成這個神祕的任務。我正在寫一些python來從現有的腳本做一些不同的工作。現有的代碼似乎可以工作,但這很瘋狂,我希望用更多的python-y方法來解析比特。什麼是可讀/現代的解析基於位的錯誤代碼的方法?
首先,解釋我對當前代碼的閱讀。 hrPrinterDetectedErrorState
上snmpwalk
查詢返回的錯誤代碼被編碼爲一個八位組串,通常帶有引號。所以引號與空格和換行符一起被刪除。錯誤代碼最多可以有四個字節,但如果爲零,通常會爲第二對發送空字節,因此在這種情況下會添加一對零。然後錯誤代碼被轉換爲十六進制。
現有的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)
然後,只需比較索引與錯誤字典,你就完成了。
無論如何,非常醜陋,可能相當低效。什麼是更高級的,可讀性更高的方法來實現相同的目標?
這一個勝可讀性,所以給予好評那裏,但在指數運算效率失去了一些分VS斯文的答案。所以斯文一個鼻子。 – anthropomo
我的更新如何? – Veedrac
我通常不喜歡改變我的答案,但是這個新的答案是有效率的,並且對於十六進制字符串「8000」和更高的正確答案,Sven不會出於某種原因。 – anthropomo