从文件中读取并将其模式更改为数组?

从文件中读取并将其模式更改为数组?

我有一个 CSV 文件,其中包含如下条目:

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

等等,我需要在远程思科交换机上执行一些思科命令,例如:

现在如果我做这样的事情

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

它每次都会进行 ssh 并提示我输入文件中每一行的密码,即使对于相同的 ip 地址也是如此。有什么办法可以克服这个问题吗?我正在考虑将文件中的另外两列放入一个数组中,就像单个 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 ......

等等

我该如何做到这一点,以便我可以像这样传递一个 ip 的命令数组:

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

但我仍然需要确保,如果我在 while 循环中获得类似的 ip 地址,则不应 ssh 进入它,而仅当它找到新的 ip 地址时。

我在用空的使用 ssh 以非交互方式将密码传递到远程交换机,但它也不是很好,因为如果远程命令失败,它不会出现任何错误。包括密码在内的所有内容都会记录到其日志文件中。

注意:所有 ip 的用户密码都相同

答案1

以下这些功能是一个好的开始。foo将读取 CSV 文件的内容,并填充 IP 地址数组,该数组将在每次迭代时进行检查,以便ssh不会使用同一 IP 多次执行。

# 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"
}

答案2

听起来像是 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}\"";
}

将此脚本保存到文件中,使其可执行 ( chmod +x script_file) 并像这样调用它:

$ ./script_file inputfile

两条评论:

  • 上面的代码未经测试:请自行决定使用。
  • 我第二吉皮建议:设置SSH密钥登录。

相关内容