使用Net :: SSH或创建STDIN套接字的交互式SSH会话

时间:2018-10-26 10:27:29

标签: ruby net-ssh

这不是How to SSH interactive SessionNet::SSH interactive terminal scripting. How?Ruby net-ssh interactive response/reply的副本

我正在尝试使用Net:SSH编写交互式SSH客户端,因为我已经使用它在目标主机上运行非交互式命令。

我可以直接使用system "ssh",但是这需要将连接设置,代理等转换为ssh参数。

问题是将数据从STDIN流到Shell通道。 listen_to的Net :: SSH文档说明了输入是从套接字而不是从STDIN输入时如何执行的。 $stdinIO.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 :(得分:2)

套接字实际上只不过是文件描述符而已,而且由于STDIN也是文件描述符,因此尝试尝试也无妨。

但是,您想要的是先将TTY置于原始模式以获得交互性。
这段代码似乎可以正常工作:

begin
  system('stty cbreak -echo')

  Net::SSH.start(...) do |session|
    session.open_channel do |...|
       ...
       session.listen_to(STDIN) { |stdin|
         input = stdin.readpartial(1024)
         channel.send_data(input) unless input.empty?
       }
     end.wait
   end
ensure
  system('stty sane')
end