Как пройти SSH интерактивную сессию - PullRequest
4 голосов
/ 30 октября 2011

Добрый день всем

Мне нужно выполнить команду на машине Linux, эта команда является интерактивной команда. Интерактивная команда означает, что требуется ввод, как [да, нет] или пароль дважды

мой настоящий случай. Я создаю сценарий выполнения команд и получаю результаты успешно. но на некоторых серверах логин пароль истек, поэтому мне нужно взаимодействовать с сервер для отправки текущего пароля + новый пароль (дважды)

ssh userName@10.0.0.243
userName@10.0.0.243's password:
You are required to change your password immediately (password aged)
Last login: Sun Aug  7 13:15:40 2011 from 10.0.0.28
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user userName.
Changing password for userName
(current) UNIX password:
New UNIX password:
Retype new UNIX password:

Примечания ::

  • Я использую Ruby 1.9.2
  • У меня нет проблем с выполнением команды в обычном случае
  • пожалуйста, я должен избегать обходных путей, таких как (echo "pass" | ssh -S), чтобы заставить меня проходить любые другие интерактивные ситуации.
  • Я использую библиотеки 'net / ssh'
  • Скрипт прилагается http://king -sabri.net / files / LinuxHWScanner.rb
  • Я попробовал "net / ssh / telnet", и это не помогает
  • Некоторые советы говорят, что использование 'rake / remote_task' является решением, но я не могу понять, как это работает в моем случае

если вам нужно больше простоты, вот простой код, если вы сделаете это работает, я думаю, что это решит мою предыдущую проблему

  require 'net/ssh'

  host = "10.0.0.106"
  port = 22     # SSH port
  user = 'root'     # username
  pass = "123123"   # password

Net::SSH.start( host,user,:password => pass, :port=> port , :verbose => :error ) do |session|

 puts session.exec!("passwd root")
end

1 Ответ

3 голосов
/ 30 октября 2011

Что-то вроде этого?

Net::SSH.start('10.0.0.6', 'not_root', :password => "test") do |ssh|
   ssh.open_channel do |channel|
      channel.on_request "exit-status" do |channel, data|
        $exit_status = data.read_long
      end
      channel.exec("passwd") do |channel, success|
        if success
          channel.on_data do |channel, data|
            # Don't really need this callback actually
            puts "got data: #{data.inspect}"
          end
          # You don't need this line if you're root
          channel.send_data("oldpass\n")
          channel.send_data("newpass\n")
          channel.send_data("newpass\n")
        else
           puts "FAILED"
        end
      end
      channel.wait
      puts "SUCCESS" if $exit_status == 0
   end
end

Этот файл грязный, но работает как при преждевременном завершении срока действия, так и при выдаче passwd:

Net::SSH.start('localhost', 'not_root', :password => "test") do |ssh|
  ssh.open_channel do |channel|
     channel.on_request "exit-status" do |channel, data|
        $exit_status = data.read_long
     end
     channel.on_data do |channel, data|
        puts data.inspect
        if data.inspect.include? "current"
                channel.send_data("oldpass\n");
        elsif data.inspect.include? "new"
                channel.send_data("newpass\n");
        end
     end
     channel.request_pty
     # This will just safely fail if we have already a password prompt on
     channel.exec("passwd");
     channel.wait
     # Will reflect a valid status in both cases
     puts $exit_status
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...