lendo de um arquivo e alterando seu padrão em uma matriz?

1

Eu tenho um arquivo CSV contendo entradas como esta:

ipaddress,VLAN,VLANid
10.192.168.1,vlan-xyz,3
10.192.168.1,vlan-abc,8
10.192.168.1,vlan-mnp,11
10.192.163.24,vlan-llz,3
10.192.163.24,vlan-bbz,5
10.192.163.24,vlan-xggz,23

e assim por diante e eu preciso executar alguns comandos cisco em switches cisco remotos como:

agora se eu fizer algo assim

while read ipaddress vlan vlanid
ssh user@ipaddress << 'ENDSSH'
int VLAN vlan-xyz
switchport access vlan  vlanid
wr
ENDSSH 
done < inputfile

ele vai para o ssh toda vez e me pede senha para cada linha no arquivo, mesmo para o mesmo ipaddress. Existe alguma maneira de superar isso? Eu estava pensando em colocar as outras duas colunas no arquivo em uma matriz como para um único endereço IP:

eg for IP:10.192.168.1
array="
int VLAN vlan-xyz
switchport access vlan  3
wr
int VLAN vlan-abc
switchport access vlan  8
"
for next ip ......

e assim por diante

como eu faço isso para que eu possa apenas passar uma matriz de comando para um ip como este:

while read ipaddress
ssh user@ipaddress " $array"
done < inputfile

mas ainda preciso ter certeza de que, se eu obtiver o ipaddress similar no loop while, ele não deverá ser ssh, mas apenas quando encontrar um novo ipaddress.

Estou usando vazio para passar a senha de forma não interativa para o switch remoto usando ssh, mas não é muito bom também porque não Por algum erro, se os comandos remotos falharem.Tudo incluindo as senhas são registradas em seu arquivo de log.

NOTA: todos os ips têm a mesma senha para um usuário

    
por munish 24.02.2013 / 11:07

2 respostas

1

Estas funções seguintes são um bom começo. foo lerá o conteúdo do arquivo CSV e preencherá uma matriz de endereços IP que serão verificados em cada iteração para que ssh não seja executado com o mesmo IP mais de uma vez.

# Usage: inarray "$value" "${array[@]}"
inarray()
{ 
    local n=$1 h; shift
    for h; do 
        [[ $n = "$h" ]] && return
    done
    return 1
} 

# Usage: foo "$csv_file_name"
foo()
{
    local ips=() arr=() filename="$1"
    { read; while IFS= read -r line; do
        IFS=, read -ra arr <<< "$line"
        if ! inarray "${arr[0]}" "${ips[@]}"; then
            # Do whatever you want with "${arr[@]}"
            # Example for arr:
            # arr[0]=10.192.168.1, arr[1]=vlan-xyz, arr[2]=3
            ips+=("${arr[0]}")
        fi
    done; } < "$filename"
}
    
por 15.05.2013 / 13:50
1

Parece um trabalho para Perl:

#!/usr/bin/perl

use strict;
use warnings;

my $input_file=shift//die "No input file name given.\n";
open my $if,'<',$input_file or die "Couldn't open $input_file: $!\n";

my %ip_data;

<$if>; # Throw away the header

while(<$if>){
    my ($ip,$vlan,$vlan_id)=split /\s*,\s*/;
    push $ip_data{$ip}, <<EOI;
int VLAN $vlan
switchport access vlan  $vlan_id
wr
EOI
}

close $if;

for my $ip (sort keys %ip_data){ #Fork-exec an SSH process for each IP address:
    my $pid = fork;
    $pid ? () : exec "ssh user@$ip \"$ip_data{$ip}\"";
}

Salve este script em um arquivo, torne-o executável ( chmod +x script_file ) e chame da seguinte forma:

$ ./script_file inputfile

Dois comentários:

  • O código acima não foi testado: use a seu próprio critério.
  • Eu segundo jippie 's conselho : configure o login da chave SSH.
por 05.09.2013 / 03:38