Short answer
Net::SFTP.start('host', 'user', password: 'pass', port: 22) do |sftp|
# Do stuff
end
is equivalent to :
session = Net::SSH.start('host', 'user', password: 'pass', port: 22)
sftp = Net::SFTP::Session.new(session)
sftp.connect!
# Do stuff
sftp.close_channel unless sftp.nil?
session.close unless session.nil?
Better answer
For people that couldn't find a way to actually close the connection, without using auto-closing blocks, here is how I you can achieve this :
require 'net/ssh'
require 'net/sftp'
begin
# Instance SSH/SFTP session :
session = Net::SSH.start('host', 'user', password: 'pass', port: 22)
sftp = Net::SFTP::Session.new(session)
# Always good to timeout :
Timeout.timeout(10) do
sftp.connect! # Establish connection
# Do stuff
end
rescue Timeout::Error => e
# Do some custom logging
puts e.message
ensure
# Close SSH/SFTP session
sftp.close_channel unless sftp.nil? # Close SFTP
session.close unless session.nil? # Then SSH
# If you really really really wanna make sure it's closed,
# and raise after 10 seconds delay
Timeout.timeout(10) do
sleep 1 until (sftp.nil? or sftp.closed?) and (session.nil? or session.closed?)
end
end
If you don't close the connection before performing some other task, you might sometimes experience errors like this in rails for instance :
IOError (not opened for reading) # Not closed when rendering controller action
ActionView::Template::Error (not opened for reading) # Not closed when rendering template