Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm attempting to write a bash script that collects information via SNMPv3 and generates a configuration template for a given device.

My goal is to generate a template based on the variables mibnumberX and interfaceX with X being a number determined by user input (eg. how many interfaces would you like to add? what are the names of the interfaces?)

#!/bin/bash

# Ambiguously defined variables for the sake of demonstration:

authpriv="authPriv"
devicetype="ASA"
snmpuser="username"
authhash="SHA"
authstring="authpassword"
privhash="AES"
privstring="privpassword"
ipaddress="1.1.1.1"
interface1="Inside"
interface2="Outside"
numberofifs="2"
defaultasa="yes"


# Determine how many interfaces are to be added and what their friendly names are

if [[ $defaultasa = "yes" ]];
  then
    read -p "How many interfaces would you like to add to monitoring for this device? " numberofifs
    for ((i = 1; i <= numberofifs; i++))
    do
      read -p "Please enter the name of interface number ${i} and press [ENTER]: " interface${i}
    done
fi


# Walk the ifDescr MIBs, grep with the friendly name of the interface(s) and store the last number of IF-MIB::ifDescr.16 in *mibnumberX*.

if [[ $authpriv = "authPriv" ]] && [[ $devicetype = "ASA" ]];
  then
  for ((i = 1; i <= numberofifs; i++))
  do
    eval "ifnumber=\$interface$i"
    eval "mibnumber$i=$(snmpwalk -v3 -u $snmpuser -l AuthPriv -a $authhash -A $authstring -x $privhash -X $privstring $ipaddress ifD | grep -i $ifnumber | awk -F"[<.=>]" '{print $2}')"
  done
fi


# Display interface names and MIBs

printf "Name: $interface1\n MIB number: $mibnumber1\nName: $interface2\n MIB Number: $mibnumber2\n"

Script results:

$ ./test.sh
Name: Inside
 MIB number: 15
Name: Outside
 MIB Number: 16

The intention is to cycle through the mibnumberX and interfaceX variables and print out the following template with them sprinkled in whether there are two interfaces being added or two hundred.

if [[ $authpriv = "authPriv" ]];
  then
        for ((i = 1; i <= numberofifs; i++))
    do
        printf "\ndefine service{
         service_description     Interface $interface$i
         check_command           check_snmp_V3-2!$snmpuser!$authstring!$privhash!$privstring!$authpriv!$authhash!.1.3.6.1.2.1.2.2.1.8.$mibnumber${i}!-r 1 -m RFC1213-MIB!-l Interface \n} \n\n"
    done
fi

However, the output of this section is providing no such luck:

    $ ./test.sh
Name: Inside
 MIB number: 15
Name: Outside
 MIB Number: 16

define service{
             service_description     Interface 1
             check_command           check_snmp_V3-2!username!authpassword!AES!privpassword!authPriv!SHA!.1.3.6.1.2.1.2.2.1.8.1!-r 1 -m RFC1213-MIB!-l Interface
}

define service{
         service_description     Interface 2
         check_command           check_snmp_V3-2!username!authpassword!AES!privpassword!authPriv!SHA!.1.3.6.1.2.1.2.2.1.8.2!-r 1 -m RFC1213-MIB!-l Interface
}

I'm a novice experimenting with bash and am open to any suggestions.

share|improve this question
    
I haven't parsed your entire code, but why couldn't you use arrays? –  slhck Aug 23 '13 at 20:28
1  
Thanks for the quick comment. The more research I do on this problem, the more I'm led to using arrays. Unfortunately, I haven't been able to incorporate an array as a solution successfully due to my lack of understanding in regards to arrays in general. –  one.time Aug 23 '13 at 21:09

1 Answer 1

up vote 3 down vote accepted

If you have an unlimited number of possible entries, you should use Bash's arrays as data structures, rather than introducing a new variable for each entry.

All you need to do is replace the line where you ask for the name with this (text shortened for readability):

read -p "Please enter the name … press [ENTER]: " interface[$i]

Now, $interface will be an array, containing the names of the interfaces. You can iterate over the entries by using a typical for loop, where ${interface[@]} expands to all the entries:

for name in "${interface[@]}"; do echo "$name"; done

You can also easily use this within your for ((…)) loops to access the array element at index $i with $interface[$i], like we did when assigning the name.

share|improve this answer
    
Thank you for taking the time to explain this. I tested reading the input into the $interface array and it worked great. I had to use ${interface[$i]} in the for ((...)) loop and it's now working brilliantly. However, I'm unclear how I can iterate through the $interface array in the for ((...)) loop do eval, and feed the results of the eval into an array. I was trying to iterate with a number appended to the variable with no luck. eval "mibnumber$i=$(snmpwalk ... | grep -i $interface[$i] | awk -F"[<.=>]" '{print $2}')" –  one.time Aug 24 '13 at 0:26
2  
@one.time The only syntax which works for subscripting a bash array is ${array[index]}. $array[index] does not work (unless you wanted what it produces, which is the same as ${array[0]}[index]. In other words, unlike non-array variables, the braces {} are not optional. –  rici Aug 24 '13 at 5:12
1  
@one.time It should simply be mibnumber[$i]=$(…), just like in the assignment to interface we used in the original loop. –  slhck Aug 24 '13 at 8:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.