Forum: Ruby Desperate help needed with SSH

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
F15c57282f08df25dbf058c053bf88d2?d=identicon&s=25 unknown (Guest)
on 2009-05-13 11:06
(Received via mailing list)
Hi you Ruby Guru's

I have a small problem thats driving me crazy. I am trying to connect to
multiple ssh servers (1 at a time), run a number of commands and capture
the output to a unique file for each server.

My code looks like this :

-- snip --

require 'rubygems'
require 'net/ssh'

hosts = ['10.0.255.1' , '10.0.255.2' , '10.0.255.3']

instructions = [
  'sh version',
  'sh cdp ne'
  ]

hosts.each do |host|
  Net::SSH.start(host, 'user', :password => 'password') do |ssh|

    fn = File.open("output\/#{host}.txt", 'w')
    instructions.each do |command|
      fn.puts "|--------\[#{command}\]--------------------------"
      fn.puts ssh.exec!(command)
    end
    fn.close
  end
end

-- snip --

When I run this I get the following error :

Net::SSH::ChannelOpenFailed: (4)

If I remove the instructions.each loop and run only a single command.
Life
is good and it all works. If I add a second ssh.exec! or the loop, the
error returns.

It appears that the ssh.exec! closes the connection. How do I keep it
open
to allow me to run a second command?

Alan.
Cb6bbc826cd7d9238a2fae344958f7ec?d=identicon&s=25 Sandor Szücs (Guest)
on 2009-05-16 23:27
(Received via mailing list)
On 13.05.2009, at 11:05, alan@isdial.net wrote:
>  ]
These instructions looks strange for me. Are you sure that these run
on all hosts?

Try to use other instructions that should work like
["echo foo", "sh -c 'echo bar'"]

Maybe your instructions kill the shell environment by calling exec
or something similar.

> hosts.each do |host|
>  Net::SSH.start(host, 'user', :password => 'password') do |ssh|
     File.open("output/#{host}.txt", 'w') do |fn|
>
>    instructions.each do |command|
>      fn.puts "|--------\[#{command}\]--------------------------"
>      fn.puts ssh.exec!(command)
>    end
    end
>
>  end
> end
>
> -- snip --

This part should be ok, but you can improve your code and use a block
for File.open().

  File.open("output/#{host}.txt", 'w') do |fn|
   ..
  end # fn.close not needed, because the block end close the file
already.

> When I run this I get the following error :
>
> Net::SSH::ChannelOpenFailed: (4)
>
> If I remove the instructions.each loop and run only a single
> command. Life
> is good and it all works. If I add a second ssh.exec! or the loop, the
> error returns.

Calling ssh.exec!() twice in a session is not a problem.

irb> Net::SSH.start(host, user, :password => passwd) do |ssh|
irb>   ['sh -c "echo foo"', 'echo bar'].each do |command|
irb>    puts ssh.exec!(command)
irb>   end
irb> end
foo
bar


hth. regards, Sandor
Szücs
F15c57282f08df25dbf058c053bf88d2?d=identicon&s=25 Alan Claughan (Guest)
on 2009-05-18 19:24
(Received via mailing list)
Hi Sandor

Thanks for the reply.

The host I am connecting to is a Cisco Router. The commands definitely
work on a manual SSH session from my terminal

The first command always works.
I get the channel failure when trying to run the second command.
I tried swapping the two commands around, but I get the same failure.

I used the following code to talk to my mac:

require 'rubygems'
require 'net/ssh'

  Net::SSH.start('127.0.0.1', 'user', :password => 'password') do |ssh|
    ssh.exec "ls -al"
    ssh.exec "pwd"
    ssh.exec "ps -axe"
    ssh.loop
  end

Which worked great. I then changed the IP address and replaced the
commands with router commands:

require 'rubygems'
require 'net/ssh'

  Net::SSH.start('10.0.255.1', 'name', :password => 'password') do |ssh|
    ssh.exec "sh ver"
    ssh.exec "cdp ne"
    ssh.loop
  end

And it fails at the second ssh.exec, so I'm guessing this is related
to the Cisco SSH Server.

Alan.

On 17 May 2009, at 12:26 AM, Sandor Szücs wrote:
Cb6bbc826cd7d9238a2fae344958f7ec?d=identicon&s=25 Sandor Szücs (Guest)
on 2009-05-18 23:08
(Received via mailing list)
On 18.05.2009, at 19:23, Alan Claughan wrote:

> And it fails at the second ssh.exec, so I'm guessing this is related
> to the Cisco SSH Server.


Ack.
Maybe there are options that you can set on the router to let the
channel open?

regards, Sandor
Szücs
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-05-19 15:49
unknown wrote:
> I have a small problem thats driving me crazy. I am trying to connect to
> multiple ssh servers (1 at a time), run a number of commands and capture
> the output to a unique file for each server.

Try using Net::SSH::Telnet (which is something I wrote to talk to
routers). It hides the Net::SSH API behind a simple Net::Telnet one, and
as a side benefit, you can write code which connects transparently using
either telnet or ssh.

Alternatively, looking at the Net::SSH::Telnet code may show you how to
drive Net::SSH successfully.

HTH,

Brian.
This topic is locked and can not be replied to.