メモの日々


2009年05月07日(木) [長年日記]

  • 長ーい連休は終了。特別なイベントは無く、淡々と過ごした。
  • 今日は6日だと思っていたら7日だった。6日まで休みだったのか!定期券が切れてしまった。

[ruby] Net::SSH.start() は close を保証しない

RubyでNet::SSH version 2.xを使っている(バージョンは2.0.11)。

Net::SSH.start()をブロック付きで呼び出したときは File.open() などと同様に close が保障されることを期待していたが、そうではないようだ。ブロック内で例外が投げられると session が close されない。バグなのかな。

次のスクリプトで動作確認した。

#!/usr/bin/ruby

require "rubygems"
require "net/ssh"

include Net::SSH::Prompt

def parse_args
  if ARGV.size < 2 || ARGV.size > 3
    $stderr.puts "Usage: #{$0} HOST USER [PASSWORD]"
    exit 2
  end
  host = ARGV[0]
  user = ARGV[1]
  password = ARGV[2] || prompt("Enter password for #{user}@#{host}:", false)
  return host, user, password
end

def ssh_start(host, user, password)
  sss = nil
  begin
    Net::SSH.start(host, user, :password => password) { |session|
      sss = session
      raise
    }
  rescue => ex
    puts "Rescued: #{ex.message}"
  end
  puts "Session#closed?: #{sss.closed?}"
end

def file_open(path)
  fff = nil
  begin
    File.open(path) { |f|
      fff = f
      raise
    }
  rescue => ex
    puts "Rescued: #{ex.message}"
  end
  puts "File#closed?: #{fff.closed?}"
end

ssh_start(*parse_args)
file_open($0)

実行結果は次の通り。

$ ./closetest.rb localhost kenichi
Enter password for kenichi@localhost:
Rescued:
Session#closed?: false
Rescued:
File#closed?: true