Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a CSV file containging entries like this :

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

and so on and i need to execute some cisco commands on remote cisco switches like :

now if i do somehting like this

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

it is going to ssh everytime and prompt me for password for each and every line in the file even for the same ipaddress. Is there any way to get over with this. I was thinking of putting a the other two columns in the file into an array like for a single ip addresses:

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 ......

and so on

how do i do this so that i can just pass an array of command for an ip like this :

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

but still i need to make sure that if i get the similar ipaddress in the while loop it should not ssh into it but only when it finds a new ipaddress.

I am using empty to pass the password non-interactively to the remote switch using ssh but its not very good also beacuse it doesn't hrough any erros if the remote commands fail.everything including passwords are logged into its log file.

NOTE : all the ips have the same password for a user

share|improve this question
3  
Set up key authentication on the Cisco boxes. It is a lot of work the first time, but once it works you can easily (and still secure) log on to the machines. –  jippie Feb 24 '13 at 18:10
add comment

2 Answers

These following functions are a good start. foo will read the contents of the CSV file, and will populate an array of IP addresses which will be checked on each iteration so that ssh will not be executed with the same IP more than once.

# 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"
}
share|improve this answer
add comment

Sounds like a job for 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}\"";
}

Save this script to a file, make it executable (chmod +x script_file) and call it like so:

$ ./script_file inputfile

Two comments:

  • The above code is untested: use at your own discretion.
  • I second jippie's advice: set up SSH key login.
share|improve this answer
add comment

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.