Сценарий Bash для анализа вывода SNMP

Я работаю над мониторингом устройства 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

Что мне не хватает?


Изменить: Причина, по которой я этого не сделал? t pipe, сейчас я получаю примерно такой результат:

Drive online (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Драйв онлайн (1) Drive online (1)

Но я ожидаю что-то вроде этого:

Drive1 online (1) Drive2 онлайн (1) Drive3 онлайн (1) Drive4 онлайн (1) Drive5 онлайн (1) Drive6 онлайн (1) Drive7 онлайн (1) Drive8 онлайн (1) Drive9 онлайн (1) Drive10 онлайн (1) Drive11 онлайн (1) Drive12 онлайн (1) Drive13 онлайн (1) Drive14 онлайн (1) Drive15 онлайн (1) Drive16 в сети (1)

0
27.01.2017, 22:05
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.

, где число после Drive строго увеличивается на единицу для каждой строки, тогда вам понадобится счетчик в цикле:

while read -r line; do 
  printf 'Drive%d %s\n' "$(( ++count ))" "$line"
done
1
28.01.2020, 02:46

Теги

Похожие вопросы