How to get exit status with Ruby's Net::SSH library?

Viewed 11799

I have a snippet of code, simply trying to execute a script on a remote server, in the event that it fails, I'd like to make a follow-up call, imagine this:

require 'rubygems'
require 'net/ssh'
require 'etc'

server = 'localhost'

Net::SSH.start(server, Etc.getlogin) do |ssh|
  puts (ssh.exec("true")  ? 'Exit Success' : "Exit Failure")
  puts (ssh.exec("false") ? 'Exit Success' : "Exit Failure")  
end

I would expect (ignoring that stdout and stderr are printed in my contrived example) - but first line should exit with 0 which I would expect Ruby would interperate as false and display "Exit Failure" (sure, so the logic is wrong, the ternary needs to be flipped) - but the second line should exit with the opposite status, and it doesn't.

I can't even find anything in the documentation about how to do this, and I'm a little worried that I might be doing it wrong?!

3 Answers

For newer versions of Net::SSH, you can just pass a status hash to Net::SSH::Connection::Session#exec:

status = {}

Net::SSH.start(hostname, user, options) do |ssh|
  channel = ssh.exec(command, status: status)
  channel.wait # wait for the command to actually be executed
end

puts status.inspect
# {:exit_code=>0}

By default, exec streams its output to $stdout and $stderr. You can pass a block to exec to do something different, a la:

ssh.exec(command, status: status) do |ch, stream, data|
  if stream == :stdout
    do_something_with_stdout(data)
  else
    do_something_with_stderr(data)
  end
end

This works on 6.1.0 - not sure about availability for older versions. See http://net-ssh.github.io/net-ssh/Net/SSH/Connection/Session.html#method-i-exec for more details.

Related