Как получить статус выхода с Ruby Net:: SSH-библиотекой?
У меня есть фрагмент кода, просто пытающийся выполнить script на удаленном сервере, в случае его отказа, я хотел бы сделать последующий вызов, представьте это:
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
Я бы ожидал (игнорируя, что stdout и stderr напечатаны в моем надуманном примере), но первая строка должна выйти с 0
, которую я ожидаю, что Ruby будет взаимодействовать как false
и отобразить "Exit Failure" (конечно, так логика ошибочна, троицу нужно перевернуть), но вторая строка должна выйти с противоположным статусом, и это не так.
Я даже не могу найти что-либо в документации о том, как это сделать, и я немного обеспокоен тем, что, возможно, я ошибаюсь?!
Ответы
Ответ 1
Я нашел следующий способ работы с Net:: SSH гораздо полезнее. Он предоставляет вам отличные stdout
и stderr
, exit code
и exit signal
.
require 'rubygems'
require 'net/ssh'
require 'etc'
server = 'localhost'
def ssh_exec!(ssh, command)
stdout_data = ""
stderr_data = ""
exit_code = nil
exit_signal = nil
ssh.open_channel do |channel|
channel.exec(command) do |ch, success|
unless success
abort "FAILED: couldn't execute command (ssh.channel.exec)"
end
channel.on_data do |ch,data|
stdout_data+=data
end
channel.on_extended_data do |ch,type,data|
stderr_data+=data
end
channel.on_request("exit-status") do |ch,data|
exit_code = data.read_long
end
channel.on_request("exit-signal") do |ch, data|
exit_signal = data.read_long
end
end
end
ssh.loop
[stdout_data, stderr_data, exit_code, exit_signal]
end
Net::SSH.start(server, Etc.getlogin) do |ssh|
puts ssh_exec!(ssh, "true").inspect
# => ["", "", 0, nil]
puts ssh_exec!(ssh, "false").inspect
# => ["", "", 1, nil]
end
Надеюсь, что это поможет.
Ответ 2
Основываясь на ответе flitzwald - я обезьяна заплатил мою версию этого в Net:: SSH (Ruby 1.9 +)
class Net::SSH::Connection::Session
class CommandFailed < StandardError
end
class CommandExecutionFailed < StandardError
end
def exec_sc!(command)
stdout_data,stderr_data = "",""
exit_code,exit_signal = nil,nil
self.open_channel do |channel|
channel.exec(command) do |_, success|
raise CommandExecutionFailed, "Command \"#{command}\" was unable to execute" unless success
channel.on_data do |_,data|
stdout_data += data
end
channel.on_extended_data do |_,_,data|
stderr_data += data
end
channel.on_request("exit-status") do |_,data|
exit_code = data.read_long
end
channel.on_request("exit-signal") do |_, data|
exit_signal = data.read_long
end
end
end
self.loop
raise CommandFailed, "Command \"#{command}\" returned exit code #{exit_code}" unless exit_code == 0
{
stdout:stdout_data,
stderr:stderr_data,
exit_code:exit_code,
exit_signal:exit_signal
}
end
end