É possível fazer um loop através de variáveis, com números anexados ao nome da variável, em bash?

2

Estou tentando escrever um script bash que coleta informações via SNMPv3 e gera um modelo de configuração para um determinado dispositivo.

Meu objetivo é gerar um modelo baseado nas variáveis mibnumberX e interfaceX com X sendo um número determinado pela entrada do usuário (por exemplo, quantas interfaces você gostaria de add? quais são os nomes das 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"

Resultados do script:

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

A intenção é percorrer as variáveis mibnumberX e interfaceX e imprimir o seguinte modelo com elas, se houver duas interfaces sendo adicionadas ou duzentas.

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

No entanto, a saída desta seção não oferece essa sorte:

    $ ./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
}

Sou um novato a experimentar o bash e estou aberto a sugestões.

    
por one.time 23.08.2013 / 22:16

1 resposta

3

Se você tiver um número ilimitado de entradas possíveis, use as matrizes do Bash como estruturas de dados, em vez de introduzir uma nova variável para cada entrada.

Tudo o que você precisa fazer é substituir a linha em que você pede o nome por isso (texto encurtado para legibilidade):

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

Agora, $interface será uma matriz contendo os nomes das interfaces. Você pode iterar as entradas usando um loop típico for , em que ${interface[@]} se expande para todas as entradas:

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

Você também pode usar isso facilmente em for ((…)) loops para acessar o elemento da matriz no índice $i com $interface[$i] , como fizemos ao atribuir o nome.

    
por 23.08.2013 / 23:28

Tags