Ответьте на приглашение SSH перед первой командой с помощью Ruby и Net::SSH.

StackOverflow https://stackoverflow.com/questions/2223194

  •  19-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь подключиться, используя net :: ssh, к серверу, который сразу после входа в систему выполняет сценарий, который требует ввода от пользователя.Пользователь должен ввести «1» или «2», после чего он получит некоторые данные через терминал.

Моя проблема в том, что, хотя я могу подключиться, я не могу найти способ отправить «1 » на сервер и получить выходные данные.

Следующий код останавливается на «INFO -- net.ssh.connection.session[80906b74]:канал_open_confirmation:0 0 0 32768".

Использование Channel.exec( "1 " ) вместо Channel.send_data, что неудивительно, также не работает.

Net::SSH.start('host', 'user', :password => "pass", :auth_methods => ["password"], :verbose => :debug) do |session|

  session.open_channel do |channel|

    channel.on_data do |ch, data|
      STDOUT.print data
    end 

    channel.send_data( "1\n")

  end

  session.loop
end    

Есть идеи, кто-нибудь?

заранее спасибо

Это было полезно?

Решение

Можете ли вы убедиться, что ваш send_data звонок происходит после вы получаете приглашение от удаленного сервера?Попробуйте построить channel.on_data блокировать вокруг своего send_data вызовите, чтобы убедиться, что вы получили ожидаемое приглашение от сервера перед отправкой ответа.

Возможно, вы не захотите использовать exec здесь.Из документации для Net::SSH::Connection::Channel:

Отправляет запрос канала с просьбой вызвать данную команду.

Вы хотите отправить текстовую строку для ответа на приглашение, а не для вызова команды.Документы показывают exec используется для отправки полных команд CLI, таких как «ls -l /home».

Вместо, send_data вероятно, это то, что вы хотите.Документы показывают, что он использовался для отправки произвольного текста, такого как channel.send_data("the password\n").Однако обратите внимание на это предложение в документации:

Обратите внимание, что он не сразу отправляет данные по каналу, но вместо этого просто добавляет данные данные в выходной буфер канала, подготовительную к упаковке и отправке в следующий раз, когда соединение принимает данные.

Возможно, вы захотите взглянуть на channel.request_pty.Похоже, он предназначен для взаимодействия с консольным приложением.

Если вы пытаетесь (по сути) создать сценарий сеанса SSH, который обычно делаете вручную, возможно, вам будет проще использовать expect-подобный интерфейс (например, гем типа sshExpect возможно, стоит попробовать).

Другие советы

Спасибо всем за указатели.Мне удалось понять проблему: помимо использования Channel.request_pty необходимо было также запросить оболочку.Следующее, наконец, работает так, как ожидалось:

Net::SSH.start('host', 'user', :password => "pass", :auth_methods => ["password"]) do |session|

  session.open_channel do |channel|

    channel.request_pty do |ch, success| 
      raise "Error requesting pty" unless success 

      ch.send_channel_request("shell") do |ch, success| 
        raise "Error opening shell" unless success  
      end  
    end

    channel.on_data do |ch, data|
      STDOUT.print data
    end 

    channel.on_extended_data do |ch, type, data|
      STDOUT.print "Error: #{data}\n"
    end

    channel.send_data( "1\n" )

    session.loop
  end  
end    

Я не очень хорошо знаком с библиотеками Net::SSH, поэтому не могу помочь с этим как таковым, но похоже, что вы можете добиться того, чего хотите, используя Капистрано.

Например, у меня есть задача capistrano, которая подключается к удаленному серверу, запускает команду, которая ожидает ввода, а затем продолжает работу.Capistrano заботится об удаленном вводе-выводе.Может быть, это может быть решением для вас?

Надеюсь, поможет!

Если я выполню "1\n" в оболочке я получаю ответ: bash: 1: command not found

Если я выполню echo "1" Я получил: 1

Вы уверены, что хотите попробовать выполнить отправляемый текст?Возможно, вы искали что-то вроде:

output = ""
Net::SSH.start('host', 'user', :password => "pass") do |ssh|
   output = ssh.exec! "echo 1"
end
puts output

Я не разбираюсь в этой библиотеке, но по SSH вы можете открыть несколько каналов.Возможно, сервер отвечает только на первый канал по умолчанию, и если вы откроете другой, вы получите новую оболочку.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top