Using ruby ​​gem net-ssh-multi to execute sudo command on multiple servers at the same time

In a previous question, I found out how to start ssh sessions on authentication with a password on multiple servers to run a single command. Now I need to execute the "sudo" command. The problem is that net-ssh-multi does not allocate the pty terminal that sudo needs to run, resulting in the following error:

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

According to the documentation , the pseudo-terminal can be allocated by calling the method on the channel object, however the following code does not work: it generates the "no tty" error above:

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]

+4
source share
3 answers

Can you try something like this:

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

In this case, 'sudo' is inside.

+7
source

You need to request pty before running the command.

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

You can also remove the tty request from / etc / sudoers. To do this, run visudo and comment on Defaults requiretty

+3
source

This is what I did thanks to @Christian and this 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 
+1
source

All Articles