【问题标题】:Using the ruby gem net-ssh-multi to execute a sudo command on multiple servers at once使用 ruby​​ gem net-ssh-multi 一次在多个服务器上执行 sudo 命令
【发布时间】:2011-09-05 20:28:11
【问题描述】:

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

[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 补丁级别 72)[i386-cygwin]

【问题讨论】:

    标签: ruby sudo net-ssh


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      你能试试这样的吗:

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

      在这种情况下,“sudo”在里面。

      【讨论】:

        【解决方案3】:

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

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

        你也可以从 /etc/sudoers 中删除 tty 请求。要做到这一点,请运行 visudo 并评论 Defaults requiretty

        【讨论】:

        • 哦,只有我可以对 sudoers 文件做任何事情,或者甚至使用密钥之类的东西进行身份验证,我的生活才会轻松得多!但我有不少于两个独立的、庞大的公司官僚机构站在我身后的好处,坦率地说,重写 ssh 协议比获得批准在这些服务器上更改一件事更容易。不过谢谢你的提示。
        • 这是在里面:Net::SSH.start('HOST', 'USER', :keys=&gt;["~/.ssh/my_ssh_key"]) do |session| ... end 对吗?
        猜你喜欢
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        • 2012-02-26
        • 2013-09-05
        • 2022-06-06
        • 1970-01-01
        • 2013-11-22
        • 1970-01-01
        相关资源
        最近更新 更多