前回までは、sshやシェルスクリプトのexpectコマンドでサーバへのログインについて書いて来ました。今回は、Rubyを使って、サーバにログインする方法を調べてみました。
Expect コマンドでパスワードなしでログインする方法(telnet,ssh,scp) | Futurismo
環境
前回と同じように、CygwinからUbunsuサーバに接続してみる。
- 接続先: ubuntu
- 接続元: cygwin
- Ruby 1.9.3
net/telnetライブラリを利用して、telnetする
Rubyでtelnetを利用するためには、net/telnetライブラリを読み込んで利用します。公式リファレンスはココ。
ポイントは以下
- require ‘net/telnet’
telnet用のライブラリを読み込む - new
telnetオブジェクトを生成して、リモートホストと接続。 - login
ユーザ名とパスワードを用いてログインする - cmd
コマンドを実行する。 - close
telnetを終了する。
# -*- coding: utf-8 -*-
require 'net/telnet'
# リモートホスト に接続
# タイムアウトは 10 秒
telnet = Net::Telnet.new("Host" => "192.168.118.129",
"Timeout" => 10)
# ログインし、プロンプトが出るまで待ち合わせる
telnet.login("tsu-nera", "*******") {|c| print c}
# ls コマンドを実行し、実行後、プロンプトが出るまで待ち合わせる
telnet.cmd("ls") {|c| print c}
# ログインセッションの終了
telnet.cmd("exit") {|c| print c}
telnet.close
Expectコマンドを利用した時よりも、実行速度は遅い。そして、interactのような、telnetの途中で標準入出力をキーボードに切り替える方法もないようだ。
ただし、シェルスクリプトに比べてずっとコードが綺麗。
pyt,expectを利用してtelnetする
こっちが本題。Rubyにもシェルスクリプトと同様なexpectがあった。これを利用する。
pytは擬似tty(Pesude tty)。
これで、擬似的にttyを生成して、標準入出力を操作する。
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'pty'
require 'expect'
# ログイン情報を入力
hostname="ubuntu"
username="tsu-nera"
password="*******"
# expect で読み込んだ内容を標準出力に出力するおまじない
$expect_verbose=true
PTY.spawn("telnet -l #{username} #{hostname}") do |r,w|
w.sync = true
r.expect(/Password: /) { w.puts "#{password}" }
r.expect(/[$%#]/) { w.puts "ls" }
r.expect(/[$%#]/) { w.puts "exit" }
end