Net::SSH exec command on remote host

S

saga99x

I try to use Net::SSH to exec command on remote host. A session was
openned and a few command should be exec and get the output.
It always failed to get the output of second cmd no matter what
command it is. Here is the code

def do_cmd(s, cmd) #session, command
s.open_channel do |channel|
channel.on_data do |ch, data|
puts "#{data}"
end
channel.exec cmd, true
end
end


session = Net::SSH.start(h,u,p) #hostname, userid, passwd
do_cmd(session, "version") # first cmd
do_cmd(session, "version") # 2nd cmd
session.loop
session.close

Here is the error:
/usr/local/lib/ruby/site_ruby/1.8/net/ssh/transport/packet-stream.rb:
202:in `<<': can't convert nil into String (TypeError)
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/transport/
packet-stream.rb:202:in `read'
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/transport/
packet-stream.rb:153:in `get'
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/transport/
packet-stream.rb:147:in `synchronize'
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/transport/
packet-stream.rb:147:in `get'
from /usr/local/lib/ruby/site_ruby/1.8/needle/lifecycle/
proxy.rb:60:in `__send__'
from /usr/local/lib/ruby/site_ruby/1.8/needle/lifecycle/
proxy.rb:60:in `method_missing'
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/transport/
session.rb:247:in `wait_for_message'
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/transport/
session.rb:242:in `loop'
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/transport/
session.rb:242:in `wait_for_message'
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/connection/
driver.rb:148:in `process'
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/connection/
driver.rb:138:in `loop'
from /usr/local/lib/ruby/site_ruby/1.8/net/ssh/session.rb:
164:in `loop'

Could anyone give me a hint?
 
S

saga99x

Hi,

do you have installed the ruby openssl bindings?

Andre

The ssh authentication works fine. Login to the remote host
successfully. I assume the openssl binding are installed.
 
C

Caveman

Saga,

There are many ways to execute commands via the NET::SSH. Here is one
option that will do what you want it to do:


This encapsulates the commands:
Net::SSH.start(h,u,p) do |session|
shell = session.shell.sync
cmd = shell.send_command "whatevercommand\n"
p cmd.stdout
cmd2 = shell.send_command "whatevercommand\n"
p cmd2.stdout
end
end

Or, if it's a standard command, you can do this:
Net::SSH.start(h,u,p) do |session|
shell = session.shell.sync
cmd = shell.whatevercommand
p cmd.stdout
cmd2 = shell.whatevercommand
p cmd2.stdout
end
end

Cool thing about this is, if you are running a command that pipes to
stderr, you can also capture that with cmd.stderr.

Using the shell.send_command method allows you to send entire strings
to be executed, such as:

cmd = shell.send_command("cat /proc/partitions")
p cmd.stdout

Which allows you to capture the stdout as a string, then parse it as
such:

cmd = shell.send_command("cat /proc/partitions")
devices = out.stdout
devices.gsub!(/\n/,'')
devices.gsub!(/([0123456789])/, '')
disks<<devices.scan(%r/ (.*) /)
puts disks.uniq!

Which "should" give you a list of all unique mounted drives in your
system... just as an example.

Hope this helps,
Caveman
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top