Today lets have a look at one way to construct a nagios plugin in bash. I would usually write these in perl, but sometimes that is not possible. This plugin is actually written to be executed using NRPE.

<code>#!/bin/bash
# bash nagios plugin

###
# Variables
###
OK=0
WARNING=1
CRITICAL=2
UNKNOWN=-1
TO_RETURN=${OK}
TO_OUTPUT=''

# Print usage information and exit
print_usage(){
    echo -e "\n" \
    "usage: ./check_uptime -w 20 -c 30 \n" \
    "\n" \
    "-w <days>    warning value\n" \
    "-c <days>    critical value\n" \
    "-h           this help\n" \
    "\n" && exit 1
}

###
# Options
###

# Loop through $@ to find flags
while getopts ":hw:c:" FLAG; do
    case "${FLAG}" in
        w) # Warning value
            WARNING_VALUE="${OPTARG}" ;;
        c) # Critical value
            CRITICAL_VALUE="${OPTARG}" ;;
        h) # Print usage information
            HELP=1;;
        [:?]) # Print usage information
            print_usage;;
    esac
done

###
# Functions
###

log_date(){
    echo $(date +"%b %e %T")
}

error() {
    NOW=$(log_date)
    echo "${NOW}: ERROR: $1"
    exit 1
}

warning() {
    NOW=$(log_date)
    echo "${NOW}: WARNING: $1"
}

info() {
    NOW=$(log_date)
    echo "${NOW}: INFO: $1"
}

# Do something
get_cmd_output(){
    #generate output
    echo `uptime | sed 's/.*up \([0-9]*\) day.*/\1/'` || error "failed to run command"
}

###
# Program execution
###
[ "${HELP}" ] && print_usage

if [ ${WARNING_VALUE} ] && [ ${CRITICAL_VALUE} ]
then
    CMD_OUTPUT=$(get_cmd_output)
else
    print_usage
fi

if [ "${CMD_OUTPUT}" ] && [ ${CMD_OUTPUT} -gt ${CRITICAL_VALUE} ]
then
    TO_RETURN=${CRITICAL}
elif [ "${CMD_OUTPUT}" ] && [ ${CMD_OUTPUT} -gt ${WARNING_VALUE} ]
then
    TO_RETURN=${WARNING}
elif [ "${CMD_OUTPUT}" ] && [ ${CMD_OUTPUT} -gt 0 ]
then
    TO_RETURN=${OK}
else
    TO_RETURN=${UNKNOWN}
fi

if [ $TO_RETURN == ${CRITICAL} ]
then
    TO_OUTPUT="CRITICAL "
elif [ $TO_RETURN == ${WARNING} ]
then
    TO_OUTPUT="WARNING "
elif [ ${TO_RETURN} == ${OK} ]
then
    TO_OUTPUT="OK "
else
    TO_OUTPUT="UNKNOWN "
fi

TO_OUTPUT="${TO_OUTPUT}| uptime=${CMD_OUTPUT};$WARNING_VALUE;$CRITICAL_VALUE"

echo "$TO_OUTPUT";
exit $TO_RETURN;
</code>

Lets break it down…

<code>OK=0
WARNING=1
CRITICAL=2
UNKNOWN=-1
</code>

We define some readable names for the return codes.

<code>TO_RETURN=${OK}
</code>

Set the initial return value to OK.

<code># Do something
get_cmd_output(){
    #generate output
    echo `uptime | sed 's/.*up \([0-9]*\) day.*/\1/'` || error "failed to run command"
}
</code>

Function to obtain the value we want to check. In this case uptime.

<code>if [ "${CMD_OUTPUT}" ] && [ ${CMD_OUTPUT} -gt ${CRITICAL_VALUE} ]
then
    TO_RETURN=${CRITICAL}
elif [ "${CMD_OUTPUT}" ] && [ ${CMD_OUTPUT} -gt ${WARNING_VALUE} ]
then
    TO_RETURN=${WARNING}
elif [ "${CMD_OUTPUT}" ] && [ ${CMD_OUTPUT} -gt 0 ]
then
    TO_RETURN=${OK}
else
    TO_RETURN=${UNKNOWN}
fi
</code>

Check the value of uptime against our warning and critical values.

<code>if [ $TO_RETURN == ${CRITICAL} ]
then
    TO_OUTPUT="CRITICAL "
elif [ $TO_RETURN == ${WARNING} ]
then
    TO_OUTPUT="WARNING "
elif [ ${TO_RETURN} == ${OK} ]
then
    TO_OUTPUT="OK "
else
    TO_OUTPUT="UNKNOWN "
fi
</code>

Set the visible output of the plugin. This output is not used by nagios.

<code>TO_OUTPUT="${TO_OUTPUT}| uptime=${CMD_OUTPUT};$WARNING_VALUE;$CRITICAL_VALUE"
</code>

Construct the output string according to the nagios plugin developer guidelines.

Stay tuned. The perl version will be out soon.

For more information see: http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN201