Ошибка вывода нового плагина Nagios BASH: такой экземпляр в настоящее время существует с этим OID: ожидается целочисленное выражение

Я пытаюсь написать свой первый плагин Nagios для проверки состояния точек доступа контроллеров WLAN. Цель состояла в том, чтобы сделать некий "универсальный" плагин, но я получаю сообщение об ошибке:

.1.3.6.1.4.1.14179.2.2.1.1.3.0.: Unknown Object Identifier ()

/usr/lib/nagios/plugins/check_wlc_ap_state.sh: line 50: [: Such Instance currently exists at this OID: integer expression expected
/usr/lib/nagios/plugins/check_wlc_ap_state.sh: line 53: [: Such Instance currently exists at this OID: integer expression expected
/usr/lib/nagios/plugins/check_wlc_ap_state.sh: line 56: [: Such Instance currently exists at this OID: integer expression expected
UNKOWN-  = Such Instance currently exists at this OID

Вот мой код:

#!/bin/bash

while getopts "H:C:O:N:I:w:c:h" option; do
        case "$option" in
                H )     host_address=$OPTARG;;
                C )     host_community=$OPTARG;;
                O )     ap_op_status_oid=$OPTARG;;
                N )     ap_hostname_oid=$OPTARG;;
                w )     warn_thresh=$OPTARG;;
                c )     crit_thresh=$OPTARG;;
                h )     show_help="yes";;

        esac
done

# Help Menu
help_menu="Plugin to check AP operational status.
Example:
Check AP Status on Cisco CS5508
./check_wlc_ap_state.sh -H [Controller IP] -C [Controller Community] -O .1.3.6.1.4.1.14179.2.2.1.1.6.0 -N .1.3.6.1.4.1.14179.2.2.1.1.3.0 -w 2 -c 3

Required Arguments:
-H      WLAN Controller Address
-C      WLAN Controller RO Community String
-O      OID to AP Operation Status
-N      OID to AP Hostname
-c      Critical Threshold
-w      Warning Threshold

Optional Arguments:
-h      Display help 
"

if [ "$show_help" = "yes" -o $# -lt 1 ]; then
  echo "$help_menu"
  exit 0
fi

# Change the .1. to iso. and get the length + 1 to get rid of the trailing .
ap_op_status_oid=${ap_op_status_oid:2}
ap_op_status_oid="iso$ap_op_status_oid"
ap_op_status_oid_length=${#ap_op_status_oid}
ap_op_status_oid_length="$ap_op_status_oid_length+1"

#Get info
while read -r oid_index equal integer ap_stat;
do
        ap_index="${oid_index:$ap_op_status_oid_length}"
        ap_hostname=$(snmpget -c $host_community $host_address -v 1 $ap_hostname_oid.$ap_index | awk -F '"' '{print$2}')
        if [ "$ap_stat" -lt "$warn_thresh" ]; then
                echo -n "OK- $ap_hostname = $ap_stat | "
                exit 0;
        elif [ "$ap_stat" -eq "$warn_thresh" ]; then
                echo -n "WARNING- $ap_hostname = $ap_stat | "
                exit 1;
        elif [ "$ap_stat" -ge "$crit_thresh" ]; then
                echo -n "CRITICAL- $ap_hostname = $ap_stat | "
                exit 2;
        else
                echo -n "UNKOWN- $ap_hostname = $ap_stat | "
                exit 3;
        fi

done < <(snmpwalk -c $host_community -v 2c $host_address $ap_op_status_oid)

А вот вход и желаемый результат. Однако я не уверен, подходит ли вывод для Nagios/Icinga2.

./check_wlc_ap_state.sh -H 10.77.208.12 -C r350urc31 -O .1.3.6.1.4.1.14179.2.2.1.1.6.0 -N .1.3.6.1.4.1.14179.2.2.1.1.3.0 -w 2 -c 3

OK- AP-1 = 1 | OK- AP-2 = 1 | OK- AP-3 = 1 | OK- AP-4 = 1 | OK- AP-5 = 1 | OK- AP-6 = 1 | OK- AP-7 = 1 | OK- AP-8 = 1 |

Изменить: вот набор -x

:40+ap_op_status_oid=.3.6.1.4.1.14179.2.2.1.1.6.0
:41+ap_op_status_oid=iso.3.6.1.4.1.14179.2.2.1.1.6.0
:42+ap_op_status_oid_length=31
:43+ap_op_status_oid_length=32
:46+read -r oid_index equal integer ap_stat
::69+snmpwalk -c public -v 2c 10.77.208.12 iso.3.6.1.4.1.14179.2.2.1.1.6.0
:48+oid_index=iso.3.6.1.4.1.14179.2.2.1.1.6.0.129.196.3.1.112
:49+equal==
:50+integer=INTEGER:
:51+ap_stat=1
:52+ap_index=129.196.3.1.112
::53+awk -F '"' '{print$2}'
::53+snmpget -c public 10.77.208.12 -v 1 .1.3.6.1.4.1.14179.2.2.1.1.3.0.129.196.3.1.112
:53+ap_hostname=AP-01
:55+'[' 1 -lt 2 ']'
:56+echo -n 'OK- AP-01 = 1 | '
OK- AP-01 = 1 | :57+exit 0

person cflinspach    schedule 13.02.2017    source источник
comment
У вас есть большая строка, которую вы передаете числовому тесту. Это не работает.   -  person Charles Duffy    schedule 13.02.2017
comment
Кстати, у вас куча багов с цитированием. Запустите свой код через shellcheck.net и исправьте найденное.   -  person Charles Duffy    schedule 13.02.2017
comment
Кстати, вы ожидаете, что ap_op_status_oid_length="$ap_op_status_oid_length+1" будет математической операцией? Это не так. Возможно, вы хотите ap_op_status_oid_length=$((ap_op_status_oid_length+1)) или (( ++ ap_op_status_oid_length )) — последнее является башизмом, а первое — POSIX-совместимым.   -  person Charles Duffy    schedule 13.02.2017
comment
Кроме того, при написании кода в вопросе StackOverflow попробуйте сгенерировать минимальный, полный, проверяемый пример — минимальный смысл не содержит посторонних компонентов (таких как справка), полный и поддающийся проверке, что означает, что другие люди могут запустить его, чтобы увидеть вашу проблему и/или определить, работают ли их исправления - это означает, например, возможное жесткое программирование snmpget или snmpwalk как функций с жестко заданным выводом , или удалить их сразу, если вы можете сделать это и по-прежнему показывать проблему.   -  person Charles Duffy    schedule 13.02.2017
comment
Кроме того, echo -n на самом деле зависит от поведения, определяемого реализацией. Спецификация POSIX рекомендует использовать printf вместо этого в новом коде: printf '%s' "your string here" — это более надежная и портативная альтернатива echo -n "your string here". (См. разделы «ИСПОЛЬЗОВАНИЕ ПРИЛОЖЕНИЯ» и «ОБОСНОВАНИЕ» приведенной выше ссылки, чтобы понять, почему переносимость echo ограничена, за исключением очень ограниченной области аргументов).   -  person Charles Duffy    schedule 13.02.2017
comment
Спасибо за совет! Я не знал о shellcheck.net; Мне это нравится.   -  person cflinspach    schedule 13.02.2017
comment
Кроме того, аргумент -o для test устарел; [ "$show_help" = yes ] || [ $# -lt 1 ] — предпочтительный механизм для объединения нескольких тестов; см. нотацию '[OB]' в стандарте. Поддержка нескольких тестов в одном требует группировки, но группировка становится неоднозначной без древнего хака x$foo; рассмотрим [ ( = ) ]: он спрашивает, является ли = непустым, или спрашивает, являются ли ( и ) идентичными строками? Тест GNU предполагает последнее, но первое поддерживается.   -  person Charles Duffy    schedule 13.02.2017
comment
Если вы не делаете это в образовательных целях, плагины nagios в bash, как правило, плохая идея (плохая производительность и порождение процессов).   -  person Bruno9779    schedule 13.02.2017
comment
@ Bruno9779, я согласен с тем, что производительность собственных сценариев оболочки во многом зависит от того, как они написаны. Придерживайтесь встроенных функций, избегайте подстановки команд и подоболочек, и эти предостережения можно свести к минимуму. [ является встроенным в современных оболочках — на самом деле мы не запускаем /usr/bin/[ для каждого теста — поэтому здесь дорого обходятся вызовы snmpwalk, snmpget и awk; последние два, вызываемые внутри цикла, на самом деле самые дорогие, но если бы мы передавали несколько OID только одному вызову snmpget, эта стоимость могла бы быть значительно снижена.   -  person Charles Duffy    schedule 13.02.2017
comment
(... использование read для выполнения работы, выполняемой в настоящее время awk, также было бы полезной оптимизацией - и если на платформе с реальным Дэвидом Корном ksh93, использование этого сильно оптимизированного интерпретатора, а не bash, не повредит).   -  person Charles Duffy    schedule 13.02.2017


Ответы (1)


ap_stat содержит нечисловое содержимое. Ваш код передает его оператору теста, который требует, чтобы он анализировался как числовой.

Используйте set -x для отслеживания выполнения вашего скрипта; это облегчит диагностику подобных ситуаций.

person Charles Duffy    schedule 13.02.2017
comment
ap_stat просто возвращает 1 - person cflinspach; 13.02.2017
comment
Явно не в ситуации, когда вы получаете эту ошибку. Снова соберите журналы set -x (как при запуске PS4=':$LINENO+' bash -x yourscript). - person Charles Duffy; 13.02.2017
comment
@red_eagle, ... я предполагаю, что snmpwalk возвращает ошибку. Вы читаете первое слово этой ошибки в oid_index, второе слово в equal, третье слово в integer, а остальная часть заканчивается в ap_stat. - person Charles Duffy; 13.02.2017
comment
@red_eagle, ... чтобы регистрировать содержимое переменных, заполненных read при использовании set -x, я часто добавляю строку прямо внутри своего цикла, которая выглядит так: : oid_index="$oid_index" equal="$equal" integer="$integer" ap_stat="$ap_stat" -- поскольку : является синонимом true, она ничего не делает, когда не находится в отладке. режиме, но когда вы работаете с set -x, он показывает вам соответствующие значения. - person Charles Duffy; 13.02.2017
comment
Я добавил вывод set -x в пост - person cflinspach; 13.02.2017
comment
Примечательно, что этот вывод set -x не показывает экземпляр, в котором ошибка действительно возникает. Скорее существенное, что. - person Charles Duffy; 13.02.2017
comment
... обратите внимание, если вы получаете ошибку только при работе в производственной среде, этот вывод set -x по умолчанию находится в stderr, поэтому с bash 3.x вы можете exec 2>>/tmp/some.log перенаправить его, тогда как с bash 4.x вы можете управляйте файловым дескриптором, установив BASH_XTRACEFD, чтобы вы могли запускать что-то вроде exec 3>>/tmp/some.log; BASH_XTRACEFD=3; set -x, а журналы xtrace — и только журналы xtrace — попадут в /tmp/some.log. Если вы собираетесь сделать это таким образом, убедитесь, что вы добавили строку отладки, которую я предложил выше, поскольку у вас не будет stderr для работы. - person Charles Duffy; 13.02.2017
comment
Да, плагин работает, когда я запускаю его отдельно, но когда его запускает Icinga2, возникает ошибка. - person cflinspach; 13.02.2017
comment
Итак, как я уже сказал, настройте копию, запущенную в рабочей среде, чтобы вы могли получать set -x журналов, когда ошибка действительно возникает. - person Charles Duffy; 13.02.2017
comment
... Я рискну, что integer=No в случае, когда вы столкнетесь с ошибкой, так что на самом деле в полном сообщении нет такого экземпляра. - person Charles Duffy; 13.02.2017