0

I'm trying to run a perl script which reads a text file that contains say 500 entries, read one entry at a time and send a command.

The command is server hostname where the value of hostname is the list of hostnames in the text file.

I'm new to programming,As per my understanding we need to open the file that contains the host name and read it open (ENABLE, "<hostanmes.txt") || die "could not open output file";

use a for loop to read the 512 host names in it for($i=1; $i<=512; $i++)

But I'm not sure how to connect this file to the command server hostname

The program is incomplete.I'm struck and not really sure.Can somebody please help me with this ?

#!/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);
user3587025
  • 173
  • 1
  • 4
  • 17

2 Answers2

3

The essence of the answer is that you can interpolate the value of scalar or array variables into a double-quoted string by just naming them inside the string. For instance

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

will print

x = 42

Here are some other points about your program

  • The use for any modules should come after use strict and use warnings, which should ordinarily be the very first lines of a program

  • It is best practice to use lexical file handles with the three-parameter form of open, and if you have use autodie in place then it is pointless to check the success of the open as it has already been done for you. So

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

    should be

    open my $enable, '<', 'hostnames.txt';
    
  • Unless you need the array indices for another reason, it is best in Perl to iterate over just the array values.

Here is a rewrite of your code that takes into account these points. It looks like it will do what you need

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');
}
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • so i want the script to read one host name at a time and then execute the command. say for example, server www.google.com, then server www.yahoo.com, similarly for 512 host names – user3587025 Jun 16 '14 at 21:51
  • @user3587025: Yes. The block `while (my $server = <$enable>) { ... }` reads one line from the file and stores it in the variables `$server`. The first line of the block - `choomp $server` - removes the trailing newline from the end of the string. Thereafter `$server` can be used as required. Here, I have interpolated it into the string `"server $server"` – Borodin Jun 16 '14 at 21:54
  • @user3587025: I can't tell whether your SSH calls are correct, but originally you were capturing the response text in `$cfg` and `$cmd` (and declaring `$cmd` twice, which will have come up as a warning) and just discarding it. That is why I changed the `$ssh->exec` lines to void calls – Borodin Jun 16 '14 at 22:00
  • @user3587025: Are you aying you want to send `config`, then `server www.google.com`, `server www.yahoo.com` etc. as many times as necessary, then `exit`? That is very simple to do but you haven't made your problem clear. I have no idea what is at the other end of your SSH connection – Borodin Jun 16 '14 at 22:02
  • step 1 is to ssh to a router, step 2 is to get into the config mode, step 3 is to execute the "server hostname" command where the host name is the values in the text file and the host names cannot be repeated.i mean server www.yahoo.com will be executed only once. – user3587025 Jun 17 '14 at 00:45
  • Then use Borodin's example, and take the $ssh->exec('config'); to before the loop and the $ssh->('exit'); to after the loop. – Dimesio Jun 17 '14 at 15:02
  • @Borodin can you please take a look at this http://stackoverflow.com/questions/24295468/perl-script-for-user-interaction – user3587025 Jun 20 '14 at 01:53
0

To iterate through ENABLE once you have it you should use a simple while loop:

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

This way you do not need a for loop to iterate. So in essence you would run the "server hostname" command in this while loop:

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

Check here for details.

Dimesio
  • 665
  • 6
  • 8