1

我有一个名为“test.rb”的 Ruby 文件,我通过 Net::SCP 将它上传到服务器。

该文件的内容是:

puts "Hello, World"

如何通过 Net::SSH 执行该文件并获取 STDOUT 或 STDERR?

这是我得到的错误:

Bash: Ruby not found 

那是因为 Net::SSH 不会加载登录 shell。

我已经尝试了从 Net::SSH::Shell 到 SSHkit 和 rye 的所有方法来解决执行脚本和获取任何 STDOUT 的问题。

当我无法访问登录 shell 并获得任何 STDOUT 或 STDERR 时,如何通过 Net::SSH 执行脚本?

我正在使用 Ruby-2.1.0。

command = "ruby -e'print :hello'"
Net::SSH.start(server_connection.host, server_connection.ssh_username, port: server_connection.ssh_port, paranoid: false)  do |ssh|
  job.stdout  = ""
  job.stderr = ""
  ssh.exec! command do |channel, stream, data|
    job.stdout << data if stream == :stdout
    job.stderr << data if stream == :stderr
  end
  ssh.close
end
4

2 回答 2

1

这可能有助于解释一下:

require 'net/ssh'

# put commands to send to the remote Ruby here...
CMDs = [
  '-v',
]

print 'Enter your password: '
password = gets.chomp

Net::SSH.start('localhost', ENV['USER'], :password => password) do |ssh|

  remote_ruby = ssh.exec!('/usr/bin/which ruby').chomp
  puts 'Using remote Ruby: "%s"' % remote_ruby

  CMDs.each do |cmd|

    puts 'Sending: "%s"' % cmd

    stdout = ''
    ssh.exec!("#{ remote_ruby } #{ cmd }") do |channel, stream, data|
      stdout << data if stream == :stdout
    end

    puts 'Got: %s' % stdout
    puts
  end

end

将其保存到 Ruby 文件中。在本地计算机上打开 SSH 访问,然后运行该脚本。它会提示您输入密码,然后连接到 localhost 并获取默认 Ruby 的路径。然后它将遍历所有命令CMDs,执行它们并返回它们的 STDOUT。

有关更多选项,请参阅Net::SSH 概要

/usr/bin/which ruby

是确定系统将用于特定命令的可执行文件的标准方法。它搜索 PATH 并返回该命令的路径。如果 Ruby 与操作系统捆绑在一起或使用 yum 或 apt-get 安装,那么对于 *nix 机器,通常是 /usr/bin/ruby。如果您从源代码安装它,它可能位于 /usr/local/bin/ruby 中。

如果您使用 RVM 或 rbenv 或 Homebrew,则必须嗅出它们的存在,并使用其作者推荐的任何技巧。这段代码会挂起一段时间,然后可能会引发异常。

在我的机器上,运行该代码输出:

输入您的密码:some(secret)thang
使用远程 Ruby:“/usr/bin/ruby”
发送:“-v”
得到:ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]
于 2014-01-03T05:09:43.270 回答
0

尝试这个:

 ssh username@host "ruby -e'print :hello'"

这将在主机上执行 Ruby,并以与在远程机器上运行任何其他脚本相同的方式为您提供输出。

require 'net/ssh'

host = "localhost"
username = "tuxdna"
password = "SOMEAWESOMEPASSWORDHERE"
command = "ruby -e'print :hello'"

class Job
  attr_accessor :stdout
  attr_accessor :stderr
end

job = Job.new

Net::SSH.start(host, username, password: password)  do |ssh|
  job.stdout  = ""
  job.stderr = ""
  ssh.exec! command do |channel, stream, data|
    job.stdout << data if stream == :stdout
    job.stderr << data if stream == :stderr
  end
  # ssh.close
end
p job

输出:

$ ruby myssh.rb
#<Job:0x00000002bed0a0 @stdout="hello", @stderr="">
于 2014-01-03T02:57:55.517 回答