in reply to Net::ssh vs Net::ssh::perl

The difference between the two is that Net::SSH is a wrapper, you have to have ssh installed on the machine where you are using, while Net::SSH::perl is a perl implementation of the entire protocol, so you don't need the ssh program installed on the machine.

The easiest way to issue multiple commands with the code you have is to change $cmd to be a shell (such as '/bin/sh'), and then use WRITER to write a command to the shell, and read the results from READER. You will need a way to determine when the command is finished though, so you can break out of the READER loop..

Untested code, I prefer Net::SSH::perl...

#!/usr/bin/perl use Net::SSH qw(sshopen2); use strict; my $user = "cosmicsoup"; my $host = "mybox.somewhere.com"; my $cmd = "/bin/sh"; my @commands = ('df -k','free','uptime'); sshopen2("$user\@$host", *READER, *WRITER, "$cmd") || die "ssh: $!"; foreach(@commands) { print WRITER "$_ && echo DDDOOONNNEEE\n"; while (<READER>) { chomp(); last if /DDDOOONNNEEE/; print "$_\n"; } } close(READER); close(WRITER);

Since you are using the version that uses the external ssh command anyway, you could also look at using something like Expect, and just run ssh yourself.

Replies are listed 'Best First'.
Re: Re: Net::ssh vs Net::ssh::perl
by cosmicsoup (Beadle) on Feb 19, 2003 at 20:07 UTC
    Thank you. That makes complete sense. I'll contact the SA's to see if I can have the Net::ssh::perl and expect installed on my machine.

    Louis

      and here's a little example of Expect and plain old ssh.

      #!/usr/bin/perl use strict; use warnings; $|++; use Expect; # a heading for the run my $section = shift @ARGV; my $want_stdout = 0; unless ( defined $section and length $section ) { $section = 'intentionally left blank'; $want_stdout = 1; } my $router = 'rtr_foo'; my $timeout = 20; my $tmp_log = "/tmp/ssbinfo.$$"; my $real_log = "/home/network/SSB-INFO.LOG"; my $su_pass = 'yeahright'; my $ssh_user = 'automatron'; my $ssh_id = '/home/network/bin/automatron.identity'; my $ssh = '/usr/bin/ssh'; my $ssh_spawn = "$ssh -l $ssh_user -i $ssh_id -x $router"; eval { # catch failures!!! my $e = Expect->new() or die "No new Expect!\n"; $e->log_stdout(0); # no logging yet #$e->debug(2); #$e->exp_internal(1); # debug more # $e->raw_pty(1); # didn't seem to need these #$e->stty(qw/raw -echo/); #$e->slave->stty(qw/raw -echo/); $e->spawn( $ssh_spawn ) or die "Cannot spawn ssh with: $ssh_spawn : be +cause $!\n "; my $ssb_prompt = "SSB0\\(${router} vty\\)# "; my $root_prompt = "root\@${router}% "; my $shell_prompt = '% '; my $rtr_prompt = "${ssh_user}\@${router}> "; $e->expect( $timeout, [ qr/^$rtr_prompt/ => sub { my $e = shift; $e->send("start shell\n"); exp_continue; } ], [ qr/^$shell_prompt/ => sub { my $e = shift; $e->send("su\n"); exp_continue; } ], [ qr/^Password:/ => sub { my $e = shift; $e->send("$su_pass\n"); exp_continue; } ], [ qr/^$root_prompt/ => sub { my $e = shift; $e->log_file($tmp_log, 'w'); # w for overwrite, just +in case $e->send("date\n"); $e->expect($timeout, [ qr/^$root_prompt/ => sub { my $e = shift; $e->send("vty ssb\n"); } ], ); exp_continue; } ], [ qr/^$ssb_prompt/ => sub { my $e = shift; $e->send("set syslog tty disable\n"); $e->expect($timeout, [ qr/^$ssb_prompt/ => sub { } ],) +; } ], [ 'Cannot exec' => sub { die "Cannot exec ssh with: $ssh_spawn!\n"; } ], ) or die "failed getting to the ssb!\n"; # eww! cut-n-paste evil $e->send("show heap 0\n"); $e->expect($timeout, [ qr/^---\(more\)---/ => sub { my $e = shift; $e->send("\n"); exp_continue; } ], [ qr/^$ssb_prompt/ => sub { } ], ) or die "failed command 1!\n"; $e->send("show heap 0 accounting pc\n"); $e->expect($timeout, [ qr/^---\(more\)---/ => sub { my $e = shift; $e->send("\n"); exp_continue; } ], [ qr/^$ssb_prompt/ => sub { } ], ) or die "failed command 2!\n"; $e->send("show heap 0 accounting size\n"); $e->expect($timeout, [ qr/^---\(more\)---/ => sub { my $e = shift; $e->send("\n"); exp_continue; } ], [ qr/^$ssb_prompt/ => sub { } ], ) or die "failed command 3!\n"; # # turn off logging # $e->log_file(undef); $e->send("exit\n"); $e->expect($timeout, [ qr/^$root_prompt/ => sub { } ]) or die "failed exit ssb!\n"; $e->send("exit\n"); $e->expect($timeout, [ qr/^$shell_prompt/ => sub { } ]) or die "failed exit su!\n"; $e->send("exit\n"); $e->expect($timeout, [ qr/^$rtr_prompt/ => sub { } ]) or die "failed exit shell!\n"; $e->send("exit\n"); sleep 1; 1 or die "can't screw up exit router!\n"; $e->soft_close(); $e = undef; # clean up temporary file use Fcntl qw(:flock); open(IN, '<', $tmp_log) or die "Can't find $tmp_log\n"; if ( $want_stdout ) { *NI = *STDOUT; } else { open(NI, '>>',$real_log)or die "Can't find $real_log\n"; flock(NI, LOCK_EX); } print NI $/; if ( defined $section and length $section ) { print NI "#$/# Begin: ${section}$/#$/"; } while (<IN>) { next if $. == 1 and /^date/; # just looked ugly # next two lines fix up a few syslog messages # that make it through before we could turn # them off next if /^\[/; print(NI "SSB0(rtr_foo vty)# "),next if /^SSB0\(rtr_foo vty\)# + \[/; s/---\(more\)---\r//; # damn pager s/\r//; print NI $_; } print NI $/; if ( defined $section and length $section ) { print NI "#$/# End: ${section}$/#$/"; } close(NI) if !$want_stdout; # unlocks if locked, don't close STDOUT! close(IN); }; # end great big eval if ($@) { print "$@"; } unlink $tmp_log; exit;

      which was hastily written (probably self evident) to do a couple of logins and run some commands.

      $ ssh -l automatron -i /home/network/bin/automatron.identity -x rtr_foo
      ...
      automatron@rtr_foo> start shell
      ...
      % su
      Password: ****
      ...
      root@rtr_foo% date
      ...
      root@rtr_foo% vty ssb
      .....
      SSB0(rtr_foo vty)# set syslog tty disable
      ...
      SSB0(rtr_foo vty)# show heap 0
      ...
      ---(more)---
      ...
      SSB0(rtr_foo vty)# show heap 0 accounting pc
      ...
      ---(more)---
      ...
      SSB0(rtr_foo vty)# show heap 0 accounting size
      ...
      ---(more)---
      ...
      SSB0(rtr_foo vty)# exit
      ...
      root@rtr_foo% exit
      ...
      % exit
      ...
      automatron@rtr_foo> exit