2011-05-31 42 views
4

previous question中我想出了如何在多台服务器上启动密码验证的ssh会话来运行单个命令。现在我需要能够执行“sudo”命令。的问题是,净SSH-多不分配一个伪终端(PTY),其须藤需要运行,从而导致以下错误:使用ruby gem net-ssh-multi一次在多台服务器上执行sudo命令

[127.0.0.1 : stderr] sudo: sorry, you must have a tty to run sudo

根据该documentation,伪终端可以是在方法调用到信道分配对象,然而,下面的代码不工作:它产生上面的“无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 

$红宝石--version

红宝石1.8.7( 2008-08-11 patchlevel 72)[i386-cygwin]

回答

7

你可以尝试这样的事:

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

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

+0

谢谢,那真是太棒了! – Dmitri 2011-06-01 22:04:21

3

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

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

另外,您可以从/ etc/sudoers中删除tty requeriment。要做到这一点运行visudo和评论Defaults requiretty

+0

哦,只要我可以做任何事情,sudoers文件,甚至使用的东西,像认证密钥,我的生活会更容易!但是我拥有不下于两个独立的,巨大的企业官僚体系的利益,坦率地说,重写ssh协议比获得批准改变这些服务器上的一件事更容易。但谢谢你的提示。 – Dmitri 2011-06-01 21:42:35

+0

这里面是:'Net :: SSH.start('HOST','USER',:keys => [“〜/ .ssh/my_ssh_key”])do | session | ...结束了吗? – 2013-10-02 18:35:52

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 
相关问题