Интерактивный SSH-сеанс с использованием Net :: SSH или создание сокета STDIN - PullRequest
0 голосов
/ 26 октября 2018

Это не дубликат Как использовать интерактивный сеанс SSH или Net :: SSH.Как? или Ruby net-ssh интерактивный ответ / ответ

Я пытаюсь написать интерактивный SSH-клиент, используя Net: SSH, потому что я уже использую его для запусканеинтерактивные команды на целевых хостах.

Я мог бы просто раскошелиться на system "ssh", но для этого потребовалось бы преобразовать настройки соединения, прокси и т. д. в ssh params.

Проблемапотоковая передача данных из STDIN в канал оболочки.Документация Net :: SSH для listen_to показывает, как это сделать, когда вход поступает из сокета, а не из STDIN.$stdin или IO.console не являются сокетами и, следовательно, не совместимы с Net::SSH::BufferedIo.

Есть ли способ создать сокет из STDIN, который можно использовать для этого?Или есть лучший способ отправить все от STDIN до Net::SSH::Channel до закрытия канала?

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

require 'net/ssh'
require 'io/console'
require 'io/wait'

Net::SSH.start('localhost', 'root') do |session|
  session.open_channel do |channel|
    channel.on_data do |_, data|
      $stdout.write(data)
    end

    channel.on_extended_data do |_, data|
      $stdout.write(data)
    end

    channel.request_pty do
      channel.send_channel_request "shell"
    end

    channel.connection.loop do
      $stdin.raw do |io|
        input = io.readpartial(1024)
        channel.send_data(input) unless input.empty?
      end
      channel.active?
    end
  end.wait
end

1 Ответ

0 голосов
/ 26 октября 2018

Сокеты - это не более, чем файловые дескрипторы, и, поскольку STDIN также является файловым дескриптором, попытка не повредит.получить интерактивность.
Этот код, кажется, работает нормально:

...