How to net-ssh sudo su in Ruby

net-ssh, ruby, su, sudo

Solution

`sudo` supports the `-c` option, which passes a command to the sub-shell. Here are some of the `sudo` flags that might be useful to you:

-c, --command=COMMAND
      pass a single COMMAND to the shell with -c

--session-command=COMMAND
      pass a single COMMAND to the shell with -c and do not create a new session

-m, --preserve-environment
      do not reset environment variables

-s, --shell=SHELL
      run SHELL if /etc/shells allows it

So, using something like `sudo su someuser -c 'ls;date'`, you'll execute the commands `ls` and `date` as `someuser`. Give it a try at the command-line on that host to get a feel for what you can do, then apply it to your SSH session.

See `man sudo` for more information.

Also, just as a coding tip, you can reduce:

if data =~ /\[sudo\]/ || data =~ /Password/i

to:

if (data[/\[sudo\]|Password/i])

Problem

I'm trying to figure out how to a send chain of multiple net-ssh commands after a `sudo su - #{su_user}` in Ruby. My current code is below, and hangs with the `sudo su` command, even after the `send_data "#{password}\n"`. Meanwhile, on the system, a manual execution of `sudo su - admin2` does not require a password entry. Any help would be appreciated! ``` require 'rubygems' require 'net/ssh' host = 'hostA' user = 'admin' password = 'hostA_pwd' su_user = 'Admin2' Net::SSH.start(host, user, :password => password) do |ssh| ssh.open_channel do |channel| channel.request_pty do |c, success| raise "could not request pty" unless success channel.exec "pwd; whoami; sudo su - #{su_user} ; pwd ; whoami" channel.on_data do |c_, data| if data =~ /\[sudo\]/ || data =~ /Password/i channel.send_data "#{password}\n" else result << data end end puts result end end ssh.loop end ```

Original source