【问题标题】:Perl script to read 500 entries from a file as inputPerl 脚本从文件中读取 500 个条目作为输入
【发布时间】:2014-08-06 18:56:18
【问题描述】:

我正在尝试运行一个 perl 脚本,该脚本读取一个包含 500 个条目的文本文件,一次读取一个条目并发送一个命令。

命令是server hostname,其中主机名的值是文本文件中的主机名列表。

我是编程新手,据我了解,我们需要打开包含主机名的文件并读取它open (ENABLE, "<hostanmes.txt") || die "could not open output file";

使用 for 循环读取其中的 512 个主机名for($i=1; $i<=512; $i++)

但我不确定如何将此文件连接到命令server hostname

程序不完整。我很震惊,不太确定。有人可以帮我解决这个问题吗?

#!/usr/bin/perl

## Library import
use Net::SSH::Expect;
use strict;
use warnings;
use autodie;



print "\n [INFO] script Execution Started \n";


my $ssh = Net::SSH::Expect->new (host => "ip addr",
                             password=> 'pwd',
                             user => 'username',
                             raw_pty => 1);

my $login_output = $ssh->login();

print "\n [INFO] add host rules \n";

open (ENABLE, "<hostanmes.txt") || die "could not open output file";

for($i=1; $i<=512; $i++)
{
my $cfg = $ssh->exec("config");
my $cmd  = $ssh->exec("server www.google.com");
my $cmd  = $ssh->exec("exit");
}
close(ENABLE);

【问题讨论】:

    标签: perl perl-module


    【解决方案1】:

    答案的本质是,您可以将标量或数组变量的值插入到一个双引号字符串中,只需在字符串中命名它们即可。比如

    my $x = 42;
    print "x = $x\n";
    

    将打印

    x = 42
    

    这里有一些关于你的程序的其他要点

    • 任何模块的use 应该在之后 use strictuse warnings,通常应该是程序的第一行

    • 最佳实践是使用带有open 三参数形式的词法文件句柄,如果你有use autodie,那么检查打开是否成功是没有意义的因为它已经为你完成了。所以

      open (ENABLE, "<hostanmes.txt") || die "could not open output file";
      

      应该是

      open my $enable, '<', 'hostnames.txt';
      
    • 除非您出于其他原因需要数组索引,否则在 Perl 中最好只迭代数组 values

    这是考虑到这些要点的代码重写。看起来它会满足你的需要

    use strict;
    use warnings;
    use autodie;
    
    use Net::SSH::Expect;
    
    print "\n[INFO] script Execution Started\n";
    
    my $ssh = Net::SSH::Expect->new(
      host     => "ip addr",
      password => 'pwd',
      user     => 'username',
      raw_pty  => 1,
    );
    
    my $login_output = $ssh->login;
    
    print "\n[INFO] add host rules\n";
    
    open my $enable, '<', 'hostnames.txt';
    
    while (my $server = <$enable>) {
      chomp $server;
      $ssh->exec('config');
      $ssh->exec("server $server");
      $ssh->exec('exit');
    }
    

    【讨论】:

    • 所以我希望脚本一次读取一个主机名,然后执行命令。例如,服务器 www.google.com,然后是服务器 www.yahoo.com,同样适用于 512 主机名
    • @user3587025:是的。块while (my $server = &lt;$enable&gt;) { ... } 从文件中读取一行并将其存储在变量$server 中。块的第一行 - choomp $server - 从字符串末尾删除尾随换行符。此后可以根据需要使用$server。在这里,我已经将它插入到字符串"server $server"
    • @user3587025:我无法判断您的 SSH 调用是否正确,但最初您正在捕获 $cfg$cmd 中的响应文本(并声明 $cmd 两次,这将有提出警告)并丢弃它。这就是为什么我将 $ssh-&gt;exec 行更改为 void 调用
    • @user3587025:您是不是想发送config,然后发送server www.google.comserver www.yahoo.com 等,根据需要发送多次,然后发送exit?这很简单,但你还没有把你的问题说清楚。我不知道你的 SSH 连接的另一端是什么
    • 第 1 步是 ssh 到路由器,第 2 步是进入配置模式,第 3 步是执行“服务器主机名”命令,其中主机名是文本文件中的值,并且主机名不能重复。我的意思是服务器 www.yahoo.com 将只执行一次。
    【解决方案2】:

    要在获得 ENABLE 后迭代它,您应该使用一个简单的 while 循环:

    while(<ENABLE>){
    chomp;
    //each line read from ENABLE will be stored in $_ per loop
    }
    

    这样您就不需要 for 循环来迭代。所以本质上你会在这个while循环中运行“服务器主机名”命令:

    ...
    while(<ENABLE>) {
    chomp;
        $ssh->exec("server $_");    
    }
    ...
    

    Check here了解详情。

    【讨论】:

    • 我觉得这是最好的答案!
    猜你喜欢
    • 1970-01-01
    • 2020-06-18
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2013-10-18
    • 1970-01-01
    相关资源
    最近更新 更多