I have a CSV file containging entries like this :


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
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:
int VLAN vlan-xyz
switchport access vlan  3
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

  • 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

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[@]}"
    local n=$1 h; shift
    for h; do 
        [[ $n = "$h" ]] && return
    return 1

# Usage: foo "$csv_file_name"
    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]=, arr[1]=vlan-xyz, arr[2]=3
    done; } < "$filename"

Sounds like a job for 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

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

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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