SNMP出力解析用のBashスクリプト

SNMP出力解析用のBashスクリプト

Ciscoデバイスを監視していますが、snmp出力を解析してより詳細な別々の行に印刷する必要があります。

コマンドラインから次のことができます。

snmpwalk -m /usr/share/snmp/mibs/CISCO-UNIFIED-COMPUTING-STORAGE-MIB.my -v2c -c opennms-Priv X.X.X.X .1.3.6.1.4.1.9.9.719.1.45.4.1.18 2>/dev/null | awk '{print $4}' | while read -r line ; do echo "Drive $line" ;  done

Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)

ただし、スクリプトで同じコンテンツを使用する場合:

#!/bin/bash
Output=`snmpwalk -m /usr/share/snmp/mibs/CISCO-UNIFIED-COMPUTING-STORAGE-MIB.my -v2c -c opennms-Priv 10.201.1.131 .1.3.6.1.4.1.9.9.719.1.45.4.1.18 2>/dev/null | awk '{print $4}'`

while read -r line ; do
        echo "Drive $line";

done << $Output

わかりました、

bash -x CIMC-Monitong.sh
++ snmpwalk -m /usr/share/snmp/mibs/CISCO-UNIFIED-COMPUTING-STORAGE-MIB.my -v2c -c opennms-Priv X.X.X.X .1.3.6.1.4.1.9.9.719.1.45.4.1.18
++ awk '{print $4}'
+ Output='online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)'
CIMC-Monitong.sh: line 9: warning: here-document at line 7 delimited by end-of-file (wanted `$Output')
+ read -r line
+ echo 'Drive '
Drive
+ read -r line
+ echo 'Drive '
Drive
+ read -r line

私は何を見逃していますか?


編集:パイプしない理由は、次のような出力が得られるからです。

オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1)オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1) オンライン運転(1)

しかし、私は次のように期待しています。

ドライブ1オンライン(1)ドライブ2オンライン(1)ドライブ3オンライン(1)ドライブ4オンライン(1)ドライブ5オンライン(1)ドライブ6オンライン(1)ドライブ7オンライン(1)ドライブ8オンライン(1)ドライブ9オンライン(1)ドライブ10オンライン(1)ドライブ11オンライン(1)ドライブ12オンライン(1)ドライブ13オンライン(1)ドライブ14オンライン(1)ドライブ15オンライン(1)ドライブ16オンライン(1)

ベストアンサー1

ここでは、スクリプトの仮文書<<$Outputの先頭に解釈されます。

通常、ここのドキュメントは次のように書かれています。

cat <<END_OF_INPUT
.
.
.
.
END_OF_INPUT

...しかし、$Outputここでは、ドキュメントの区切り文字として別​​の文字列を使用しても大丈夫です。

を使用しようとするかもしれませんが、これはファイル名ではなく、パイプの出力である<$Outputファイルから読み取ろうとして処理されるため、間違っています。$Output

コマンドラインと同様に、出力をwhileループにパイプしてみてください。

#!/bin/bash

snmpwalk -m /usr/share/snmp/mibs/CISCO-UNIFIED-COMPUTING-STORAGE-MIB.my \
  -v2c -c opennms-Priv X.X.X.X .1.3.6.1.4.1.9.9.719.1.45.4.1.18 2>/dev/null |
awk '{print $4}' |
while read -r line; do 
  echo "Drive $line"
done

私は出力にユーザー提供のデータ(実際にはスクリプト外のすべてのデータ)を含める必要があるときにprintf代わりに使用する傾向があります。echo

printf 'Drive %s\n' "$line"

望むより」なぜprintfがechoより優れているのですか?

修正する:

出力が次のようになる必要がある場合

Drive1 online(1)
Drive2 online(1)
... etc.

各行は1ずつ厳密に増加するため、Driveループにカウンタが必要です。

while read -r line; do 
  printf 'Drive%d %s\n' "$(( ++count ))" "$line"
done

おすすめ記事