1

私は、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で高レベルで読みやすい方法は何ですか?

4

3 に答える 3

3

単純なループを使用して、設定されたフラグのリストを取得できます。

errors = {
    15: "low paper",
    14: "no paper",
    ...
}
flags = int(hexstr, 16)
flag_indices = []
for i in range(max(errors)):
    if flags & 1:
        flag_indices.append(i)
    flags >>= 1
于 2013-09-23T14:02:09.157 に答える
2

文字列を次のように解析できるとします。

flags = int(hexstr, 16)

探していると思います

flag_indices = []
for flag in errors:
    if flags & (2**flag):
        flag_indices.append(flag)

リストを作成してインデックスを作成する代わりに、直接行うことができます

(flags >> flag) & 1

整数では、はるかに高速になります。

于 2013-09-23T13:58:45.957 に答える
0

フラグ列挙型を使用してpowershellで実行しました。次に、結果の整数を flags 列挙型にキャストすると、一致するすべてのビットが文字列として吐き出されます。 SNMP OID 出力の読み方

[hrPrinterDetectedErrorState]37124

inputTrayEmpty, serviceRequested, noToner, lowPaper
于 2019-03-29T15:30:39.900 に答える