如何通过SSH执行远程Ruby脚本文件?

时间:2014-01-03 02:54:10

标签: ruby shell ssh net-ssh

我有一个名为“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

2 个答案:

答案 0 :(得分: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 synopsis

/usr/bin/which ruby

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

如果你使用RVM或rbenv或Homebrew,你将不得不嗅出他们的存在,并使用他们的作者推荐的任何技巧。这段代码会挂起一点,然后可能会引发异常。

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

Enter your password: some(secret)thang
Using remote Ruby: "/usr/bin/ruby"
Sending: "-v"
Got: ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]

答案 1 :(得分: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="">