0

I have this script running on windows. I need help how to add secondary command to cisco devices currently only working on one device. Also how I can print out the result on file instead of the screen.

#!\usr\bin\Perl\bin\perl
use warnings;
use strict;
use NET::SSH2;

my $host = "switchA"; # use the ip host to connect
my $user = "XXX"; # your account
my $pass = "XXXX"; # your password
my $ssh2 = Net::SSH2->new();
$ssh2->debug(0);
$ssh2->connect($host) or die "Unable to connect host $@ \n";
$ssh2->auth_password($user,$pass);

#shell use

my $chan = $ssh2->channel();

$chan->exec('sh int desc');
my $buflen = 3000;
my $buf1 = '0' x $buflen;
$chan->read($buf1, $buflen);
print "CMD1:\n", $buf1,"\n";

# run another command  still not working
$chan->exec('sh ver');
my $buflen2 = 3000;
my $buf2 = '0' x $buflen2;
$chan->read($buf2, $buflen2);
print "CMD2:\n", $buf2,"\n";
6
  • 2
    I'm not sure what you're asking. Do you want to run both of the $chan->exec commands asynchronously? If so, you'll need to run them in threads (or set up some kind of event handler). Commented Dec 12, 2011 at 23:07
  • What do you mean "not working"? Does it print out an error message? Commented Dec 12, 2011 at 23:16
  • thanks guys! the first command have the out put the second one is blank just print "CMD2" I think my question is what Jack indicated " but not sure how I can add "thread" or "Handler" the script to execute both Commands. Commented Dec 12, 2011 at 23:26
  • @Jack Maney: you can not use the same Net::SSH2 object from two different threads. The SSH connection would get broken. Commented Dec 13, 2011 at 16:53
  • It is not uncommon for network devices to only accept one command/channel per connection. Commented Dec 13, 2011 at 16:56

1 Answer 1

1

If you're asking what I think you're asking, just run each $chan->exec command in its own thread (Warning: Untested):

use warnings;
use strict;
use NET::SSH2;
use threads;
use threads::shared;

#We'll be making a Net::SSH2 object in each thread, 
#so these parameters will need to be shared between the threads.
my $host :shared = "switchA"; # use the ip host to connect
my $user :shared = "XXX"; # your account
my $pass :shared= "XXXX"; # your password

#NOTE:  The shell use (via $ssh2 and $chan) has been passed
#to the subroutines foo and bar.

#Create two threads,
#one which will perform the subroutine foo,
#and the other which will perform the subroutine bar.
my $thread1=threads->create(\&foo);
my $thread2=threads->create(\&bar);

#Wait for the threads to finish.
$thread1->join;
$thread2->join;

sub foo
{
    my $ssh2 = Net::SSH2->new();
    $ssh2->debug(0);
    $ssh2->connect($host) or die "Unable to connect host $@ \n";
    $ssh2->auth_password($user,$pass);

    my $chan = $ssh2->channel();

    $chan->exec('sh int desc');
    my $buflen = 3000;
    my $buf1 = '0' x $buflen;
    $chan->read($buf1, $buflen);

    open(my $write,">","/output/file/foo") or die $!;

    print $write "CMD1:\n", $buf1,"\n";

    close($write);
}

sub bar
{
    my $ssh2 = Net::SSH2->new();
    $ssh2->debug(0);
    $ssh2->connect($host) or die "Unable to connect host $@ \n";
    $ssh2->auth_password($user,$pass);

    my $chan = $ssh2->channel();
    $chan->exec('sh ver');
    my $buflen2 = 3000;
    my $buf2 = '0' x $buflen2;
    $chan->read($buf2, $buflen2);

    open(my $write,">","/output/file/bar") or die $!;

    print $write "CMD2:\n", $buf2,"\n";

    close($write);
}

Take a look at perldoc perlthrtut for more stuff about threads.

Edited to add: The disadvantage of the approach above is that you're firing up two SSH connections (one per thread) instead of just one. An extra layer of sophistication could be added here by firing up one connection outside of the threads (and having $ssh2 as a shared variable) and then using a semaphore (or even a lock) to make sure that the remote terminal isn't confused by one thread's command trying to step on the other thread's command.

Sign up to request clarification or add additional context in comments.

5 Comments

…and to print to a file, you just specify the filehandle as the indirect object to print, like: open FILE, '>', '/some/file/name' or die "$!"; ... print FILE "CMD2:\n", …
@BRPocock - Thanks for the reminder. The edit has been made.
thanks Jack, the script has this error now "can't call method 'excec' undifined value on line 50 and 35. I don't know why this is the error now. wasn't the issue before and you didn't change anything there.
@DanielEstifanos - In the subroutines, it appears as though $chan didn't end up getting defined. Since I don't know where lines 35 and 50 fall in your code, you'll have to make sure that both $chan and $ssh2 are both properly defined and scoped properly.
line 35 is " $chan->exec('sh int desc'); line 50 is " $chan->exec('sh ver'); I have spent a lot of hours I couldn't figure out what's the issue. I didn't see any issue while running with one command but now it doesn't I don't think any conflicting issue with thread. thanks again!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.