0

I wanted to run a remote command with ruby's net::ssh and was hoping to print the output stdout but i don't see anything printed at the below code at channel.on_data

see test code:

Net::SSH.start('testhost', "root", :timeout => 10) do |ssh|
  ssh.open_channel do |channel|
    channel.exec('ls') do |_, success|
      unless success
        puts "NOT SUCCEESS:! "
      end
      channel.on_data do |_, data|
        puts "DATAAAAAA:! " # ======> Why am i not getting to here?? <=======
      end
      channel.on_extended_data do |_, _, data|
        puts "EXTENDED!!!"
      end
      channel.on_request("exit-status") do |_, data|
        puts "EXIT!!!! "
      end
      channel.on_close do |ch|
        puts "channel is closing!"
      end
    end
  end
end

and the output is:

channel is closing!

why don't i get into the block on_data? I want to grab the stdout.

note that i know the client code is able to ssh to the remote server because when I asked the command to be ls > ls.log I saw that ls.log on target host.

1 Answer 1

2

Note that opening a channel is asynchronous, so you have to wait for the channel to do anything meaningful, otherwise you are closing the connection too soon.

Try this:

Net::SSH.start('test', "root", :timeout => 10) do |ssh|
  ch = ssh.open_channel do |channel|
    channel.exec('ls') do |_, success|
      unless success
        puts "Error"
      end
      channel.on_data do |_, data|
        puts data
      end
      channel.on_extended_data do |_, _, data|
        puts data
      end
      channel.on_request("exit-status") do |_, data|
        puts "Exit"
      end
      channel.on_close do |ch|
        puts "Closing!"
      end
    end
  end

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

3 Comments

thanks but i see that channel.on_close is called without adding the ch.wait even if the operation takes 2 minutes, if it's async how the on_close is working and not closing the connection even without the ch.wait?
If you don't wait then because this code is async the application can do whatever it wants to including exiting. If it exits however then it will close all open connections, including your async one. It doesn't matter if you use ch.wait here or at any other place, but you should wait for it to finish if it's importatnt to you before the application ends
I tried running sleep 20 as the command to run without the ch.wait and i see that it's waiting for it to finish. So from one side its waiting for it to finish, but on the other side it's not sending events on the on_data I don't understand if it's waiting for the process to end why doesn't it send data to the on_data?

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.