使用ruby gem net-ssh-multi一次在多个服务器上执行sudo命令

时间:2011-05-31 22:07:16

标签: ruby sudo net-ssh

previous question中,我想出了如何在多个服务器上启动经过密码验证的ssh会话来运行单个命令。现在我需要能够执行“sudo”命令。问题是,net-ssh-multi没有分配一个伪终端(pty),sudo需要运行,导致以下错误:

  

[127.0.0.1:stderr] sudo:对不起,你必须有一个tty来运行sudo

根据documentation,可以通过对通道对象的方法调用来分配伪终端,但是,以下代码不起作用:它生成上面的“no tty”错误:

require 'net/ssh'
require 'net/ssh/multi'

Net::SSH::Multi.start do |session|


  # define the servers we want to use
  my_ticket.servers.each do |session_server|
    session.use session_server , :user =>  user_name ,  \
                              :password => user_pass
  end


 # execute commands on all servers
  session.exec 'sudo ls /root' do |channel, stream, data|
   if data =~ /^\[sudo\] password for user:/
     channel.request_pty # <- problem must be here.
     channel.send_data user_pass
   end

  end

 # run the aggregated event loop
 session.loop
end

$ ruby​​ --version

ruby​​ 1.8.7(2008-08-11 patchlevel 72)[i386-cygwin]

3 个答案:

答案 0 :(得分:8)

你可以尝试这样的事情:

  channel.request_pty do |c, success|
    if success
      command = "sudo YOUR_COMMAND"
      c.exec(command) do |c, success|
        # Some processing
      end
    end
  end

在这种情况下,'sudo'在里面。

答案 1 :(得分:3)

您需要在运行命令之前请求pty。

session.open_channel do |ch|
  ch.request_pty
  ch.exec "sudo ls /root"
end

您也可以从/ etc / sudoers中删除tty requeriment。要执行此操作,请运行visudo并发表评论Defaults requiretty

答案 2 :(得分:1)

感谢@Christian和wonderful Pastie

,这就是我要做的事情
Net::SSH::Multi.start do |session|

# define the servers we want to use
my_ticket.servers.each do |session_server|
  session.use session_server , :user =>  my_ticket.user_name ,  \
  :password => my_ticket.user_pass
end



session.open_channel do |channel|
channel.request_pty do |c, success|
  raise "could not request pty" unless success
  channel.exec   "sudo YOUR_COMMAND"
  channel.on_data do |c_, data|
  if data = /\[sudo\]/
  channel.send_data(@password + "\n")
  end  
   puts data

    end
   end
  end

# run the aggregated event loop
  session.loop
end