ybiC has asked for the wisdom of the Perl Monks concerning the following question:


 I posted (code)) Cisco Pass Mass - IOS (deprecated by node 123464) yesterday, and humbly ask Wiser Monks Than I(TM) for advice on an making it better.   In a nutshell, ciscoconf.pl uses Net::Telnet::Cisco to automate config changes to Cisco routers or switches.

I can code a single target like so: my $cisco="router1"; or read a single target from the command-line like so: my $cisco=shift;

But I'd like to read a list of targets from either the command-line or a text file.   Something like this: ciscoconf.pl router1 router2 router3 or if none spec'd at command-line then read ciscoconf.in which would look like this:
router1
router2
router3

No doubt this is Perl 101, but if I could do it myself then I'd be a Wiser Monk Than I(TM), now wouldn't I? {grin}
    cheers,
    ybiC

  • Comment on script input from (command-linetext file) list

Replies are listed 'Best First'.
Re: script input from (command-linetext file) list
by chromatic (Archbishop) on Sep 16, 2000 at 23:55 UTC
    This is untested, but I've done something like the following:
    unless (@ARGV) { open CONF, "ciscoconf" or die "We're really in trouble now: $!"; while (<CONF>) { chomp; push @ARGV, $_; } close CONF; }
    Then you can just loop through @ARGV as you feel the need.

    Granted, I was expecting a list of files to READ, and I wanted to use the magic <> construct, but something similar applies.

Re: ...input from(command-line <i>or</i> text file)list (Question Clarified)
by ybiC (Prior) on Sep 17, 2000 at 14:02 UTC
    First off, thanks and ++ to respected Monks chromatic and merlyn for such speedy responses.

    But I'm kinda slow sometimes, and often ride the "short bus" to the Monastery   ;^)   So... I re-read ovid's excellent Before You Post ..., then condensed my script down to a relevant minimum, in hopes of some charitable Monk showing me how to insert the necessary control structure(s) properly.

    A quick(?) recap for anyone who just tuned in...   cisconconf.pl is the script, it uses Net::Telnet::Cisco to connect to a Cisco router or switch and do stuff.   ciscoconf.log records the results of the script.   And ciscoconf.in is to be a list of routers (one router name/ip addr per line) for the script to connect to.   I also want to be able to call the script with a space-delimited list of routers, like so: ciscoconf.pl router1 router2 router3, included at the command-line which whould over-ride any existing .in file.

    I half understand unless, <>, while, or push individually but not how to actually plug them into my code.
        cheers,
        ybiC

    #!/usr/bin/perl -w # ciscoconf.pl use strict; use Net::Telnet::Cisco; my $pass = ''; # Cisco vty password my $timeout = '60'; # seconds of no response ti +ll Net::Telnet::Cisco gives up waiting my $infile = "/dir/subdir/ciscoconf.in" # one-per-line text-file lis +ting of Cisco devices to connect to my $logfile = "/dir/subdir/ciscoconf.log" # logfile of script results print "starting Cisco device sessions\n" # print to console, not log open (IN, "$infile") or die "Error opening $infile: $!\n" open (LOG,">$logfile") or die "Error opening $logfile: $!\n" # repeat these actions for each Cisco device at command prompt (or els +e in ciscoconf.in) # control struct(s) begin here? print LOG "####################################################### +######\n" my $cs=Net::Telnet::Cisco->new(Host=>IN, timeout=>$timeout,); $cs->login('',$pass); # vty login $cs->errmode(sub{print LOG @_, "\n"}); # error handler: print $cs- +>errmsg, "\n" print $cs->last_prompt, "\n" # print Cisco device prompt +to console print LOG $cs->last_prompt, "\n" # print Cisco device prompt +to log $cs->close; # exit Cisco session print LOG "####################################################### +######\n" # control struct(s) end here? # end actions for each Cisco device close (IN) or die "Error closng $infile: $!\n" close (LOG) or die "Error closing $logfile: $!\n" print "finished Cisco device sessions\n" # print to console, not log # END
      #!/usr/bin/perl -w # ciscoconf.pl use strict; use Net::Telnet::Cisco; my $pass = ''; # Cisco vty password my $timeout = '60'; # seconds of no response ti +ll Net::Telnet::Cisco gives up waiting my $infile = "/dir/subdir/ciscoconf.in"; # one-per-line text-file li +sting of Cisco devices to connect to my $logfile = "/dir/subdir/ciscoconf.log"; # logfile of script results print "starting Cisco device sessions\n"; # print to console, not log open (LOG,">$logfile") or die "Error opening $logfile: $!\n"; unless (@ARGV) { @ARGV = $infile; chomp(@ARGV = <>); } # repeat these actions for each Cisco device at command prompt (or els +e in ciscoconf.in) for my $dev (@ARGV) { print LOG "####################################################### +######\n"; my $cs = Net::Telnet::Cisco->new(Host=>$dev, timeout=>$timeout); $cs->login('',$pass); # vty login $cs->errmode(sub{print LOG @_, "\n"}); # error handler: print $cs- +>errmsg, "\n"; print $cs->last_prompt, "\n"; # print Cisco device prompt + to console print LOG $cs->last_prompt, "\n"; # print Cisco device prompt + to log $cs->close; # exit Cisco session print LOG "####################################################### +######\n"; } close (LOG) or die "Error closing $logfile: $!\n"; print "Finished Cisco device sessions\n"; # print to console, not log # END

      -- ar0n (just another perl joe)

        Hey, that did the trick.
        Thanks to ar0n, chromatic, and merlyn (in alphabetical order).
            cheers,
            ybiC
Re: script input from (command-linetext <i>or</i> file) list
by ybiC (Prior) on Sep 16, 2000 at 23:51 UTC
    Ack.   Forgot to escape the | in the title.
    Hmmm... forgot how to escape a | in titles.
        ybiC