ruby ssh: интерактивная команда "su": как дальше после успешного входа в систему? - PullRequest
2 голосов
/ 17 июня 2010

Я хочу работать на удаленной машине в рамках сеанса SSH:

  1. войти на удаленный сервер
  2. su
  3. сделать мою работу

С моим сценарием можно выполнить шаги 1 и 2.Выполняя команду su, я могу отправить пароль и получить ожидаемый ответ (

on_data: data = gis@v04ree:~>
got gis@v04ree:~>

Но тогда, что мне делать? Я сижу на своем канале, ничего не происходит. Какя могу заставить канал понять, что команда завершилась и что я хочу сделать мой рабочий процесс на удаленной машине?

require 'net/ssh'
require 'net/sftp'

class Connection
  def connect
host = 'host'
user = 'user'

#1. Login
Net::SSH.start(host, user) do |ssh|
  puts ssh.exec!("whoami")
  #2. su
  begin
    puts(su(ssh, "otherUser", "otherPwd"))
  rescue Exception => e
    puts e
  end
  #3. work
  puts "logged in as " << ssh.exec!("whoami")
  ssh.close
end
end

def su(ssh, user, pwd)
 channel = ssh.open_channel do |ch|
  channel.request_pty do |ch, success|
    raise "Could not obtain pty (i.e. an interactive ssh session)" if !success
  end

  command = "su - #{user}\n"
  puts "command = #{command}"
  channel.exec command do |ch, success|
    raise "could not execute command" unless success

    # "on_data" is called when the process writes something to stdout
    ch.on_data do |c, data|
      puts "on_data: data = "+data
      if data == "Password: "
        puts "Password request"
        channel.send_data "#{pwd}\n"
      end
      if data == "gis@v04ree:~> "
        #logged in as gis
        puts "got gis@v04ree:~>"
        #and now? What's next?
        #channel.eof! # <-doesn't work

        ch.exec "ls" do |ch, success| #<- doesn't work either: success is false
          unless success
            puts "alas! the command could not be invoked!"
          end
        end
      end
    end
    #wouldn't be called
    ch.on_extended_data do |c, type, data|
      puts "on_extended_data: data = #{data}"
    end
  end #end su - gis

  #which statement
  ssh.loop
  #channel.wait
end
end
end #class end

Connection.new.connect

1 Ответ

2 голосов
/ 19 марта 2011

Проблема в том, что su создает подоболочку, а net-ssh управляет самой внешней оболочкой.Это как запуск ... emacs или что-то из net-ssh, вы не можете ожидать, что net-ssh сможет узнать, как управлять этой внутренней оболочкой.

Так что вам нужно сделать, этокогда вы обнаружите, что su был успешным, вы должны отправить данные, как если бы вы просто вводили их, а затем вы можете прочитать стандартный вывод.К сожалению, вы не можете отделить stdout от stderr, поскольку он находится в подоболочке, но вы все равно можете получить результат.

Вместо использования ch.exec после успешного завершения su используйте ch.send_data "command\n" и прочитайте вывод.Не забудьте все закончить с ch.send_data "exit\n".(Обратите внимание, что \n должен следовать каждой команде для имитации нажатия клавиши ввода в консоли)

...