# Desperate help needed with SSH

**URL:** <https://www.ruby-forum.com/t/desperate-help-needed-with-ssh/167857>\
**Category:** Ruby\
**Created:** [May 13, 2009, 11:06am UTC](https://www.ruby-forum.com/t/desperate-help-needed-with-ssh/167857 "2009-05-13T11:06:56Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [May 13, 2009, 11:06am UTC](https://www.ruby-forum.com/t/desperate-help-needed-with-ssh/167857/1 "2009-05-13T11:06:56Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [May 16, 2009, 11:27pm UTC](https://www.ruby-forum.com/t/desperate-help-needed-with-ssh/167857/2 "2009-05-16T23:27:21Z")

</div>

On 13.05.2009, at 11:05, removed\_email\_address@domain.invalid 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

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [May 18, 2009, 7:24pm UTC](https://www.ruby-forum.com/t/desperate-help-needed-with-ssh/167857/3 "2009-05-18T19:24:35Z")

</div>

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:

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [May 19, 2009, 3:49pm UTC](https://www.ruby-forum.com/t/desperate-help-needed-with-ssh/167857/4 "2009-05-19T15:49:43Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [May 18, 2009, 11:08pm UTC](https://www.ruby-forum.com/t/desperate-help-needed-with-ssh/167857/5 "2009-05-18T23:08:01Z")

</div>

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
