LoginSignup
0
2

More than 3 years have passed since last update.

Rubyのnet/telnetにinteract!メソッドを実装

Last updated at Posted at 2017-01-05

NetOpsの自動化領域では標準的APIの不足のため、泣く泣くexpectで対話的プログラムを実現しているケースも多いと思う。私自身あまりexpectを使ったことはないが、expectプログラムにはinteractなるコマンドがありプロセス制御をユーザーに戻すことができる便利機能が実装されている1ことを知った。

spawn telnet $HOSTNAME
expect "login:"
send "$USERNAME\n"
expect "Password:"
send "$PASSWORD\n"
interact

同様の機能をRubyの標準モジュールであるnet/telnetにも実装してみる。

要するに標準入力から送られたキーストロークをtelnetセッションへ、またtelnetセッションからの応答を標準出力に転送してやれば良いわけで、複数ソケットからの受信待ち受けにはIO.selectが使える。

module Net
  class Telnet

    def interact!
      $stdin.raw!

      loop do
        rs, _ = IO.select([$stdin, @sock])
        rs.each do |fh|
          case fh
          when $stdin
            bs = fh.getc.chr
            if bs == "\e"
              begin
                bs << fh.read_nonblock(3)
                bs << fh.read_nonblock(2)
              rescue IO::WaitReadable
              end
            end

            @sock.syswrite(bs)
          when @sock
            bs = fh.readpartial(1024)
            $stdout.syswrite(bs)
          end
        end
      end
    rescue EOFError
      $stdout.puts "\r\n", "Conneciton closed."
      self.close
    ensure
      $stdin.cooked!
    end

  end
end


# 冒頭のexpectプログラムと同様
session = Net::Telnet.new('Host' => $hostname)
session.login($username, $password)
session.interact!

  1. 自動化領域でユーザに制御を戻すのは負けでは?という当然の意見はこの際無視する 

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2