Net::SCP implements the SCP (Secure CoPy) client protocol, allowing Ruby programs to securely and programmatically transfer individual files or entire directory trees to and from remote servers. It provides support for multiple simultaneous SCP copies working in parallel over the same connection, as well as for synchronous, serial copies.
Basic usage:
require 'net/scp' Net::SCP.start("remote.host", "username", :password => "passwd") do |scp| # synchronous (blocking) upload; call blocks until upload completes scp.upload! "/local/path", "/remote/path" # asynchronous upload; call returns immediately and requires SSH # event loop to run channel = scp.upload("/local/path", "/remote/path") channel.wait end
Net::SCP also provides an open-uri tie-in, so you can use the Kernel#open method to open and read a remote file:
# if you just want to parse SCP URL's: require 'uri/scp' url = URI.parse("scp://user@remote.host/path/to/file") # if you want to read from a URL voa SCP: require 'uri/open-scp' puts open("scp://user@remote.host/path/to/file").read
Lastly, Net::SCP adds a method to the Net::SSH::Connection::Session class, allowing you to easily grab a Net::SCP reference from an existing Net::SSH session:
require 'net/ssh' require 'net/scp' Net::SSH.start("remote.host", "username", :password => "passwd") do |ssh| ssh.scp.download! "/remote/path", "/local/path" end
By default, uploading and downloading proceed silently, without any outword indication of their progress. For long running uploads or downloads (and especially in interactive environments) it is desirable to report to the user the progress of the current operation.
To receive progress reports for the current operation, just pass a block to upload or download (or one of their variants):
scp.upload!("/path/to/local", "/path/to/remote") do |ch, name, sent, total| puts "#{name}: #{sent}/#{total}" end
Whenever a new chunk of data is recieved for or sent to a file, the callback will be invoked, indicating the name of the file (local for downloads, remote for uploads), the number of bytes that have been sent or received so far for the file, and the size of the file.
Starts up a new SSH connection using the host and username parameters, instantiates a new SCP session on top of it, and then begins a download from remote to local. If the options hash includes an :ssh key, the value for that will be passed to the SSH connection as options (e.g., to set the password, etc.). All other options are passed to the download! method. If a block is given, it will be used to report progress (see "Progress Reporting", under Net::SCP).
# File lib/net/scp.rb, line 233 233: def self.download!(host, username, remote, local=nil, options={}, &progress) 234: options = options.dup 235: start(host, username, options.delete(:ssh) || {}) do |scp| 236: return scp.download!(remote, local, options, &progress) 237: end 238: end
Starts up a new SSH connection using the host and username parameters, instantiates a new SCP session on top of it, and then begins a download from remote to local. If the options hash includes an :ssh key, the value for that will be passed to the SSH connection as options (e.g., to set the password, etc.). All other options are passed to the download! method. If a block is given, it will be used to report progress (see "Progress Reporting", under Net::SCP).
# File lib/net/scp.rb, line 233 233: def self.download!(host, username, remote, local=nil, options={}, &progress) 234: options = options.dup 235: start(host, username, options.delete(:ssh) || {}) do |scp| 236: return scp.download!(remote, local, options, &progress) 237: end 238: end
Starts up a new SSH connection and instantiates a new SCP session on top of it. If a block is given, the SCP session is yielded, and the SSH session is closed automatically when the block terminates. If no block is given, the SCP session is returned.
# File lib/net/scp.rb, line 196 196: def self.start(host, username, options={}) 197: session = Net::SSH.start(host, username, options) 198: scp = new(session) 199: 200: if block_given? 201: begin 202: yield scp 203: session.loop 204: ensure 205: session.close 206: end 207: else 208: return scp 209: end 210: end
Starts up a new SSH connection and instantiates a new SCP session on top of it. If a block is given, the SCP session is yielded, and the SSH session is closed automatically when the block terminates. If no block is given, the SCP session is returned.
# File lib/net/scp.rb, line 196 196: def self.start(host, username, options={}) 197: session = Net::SSH.start(host, username, options) 198: scp = new(session) 199: 200: if block_given? 201: begin 202: yield scp 203: session.loop 204: ensure 205: session.close 206: end 207: else 208: return scp 209: end 210: end
Starts up a new SSH connection using the host and username parameters, instantiates a new SCP session on top of it, and then begins an upload from local to remote. If the options hash includes an :ssh key, the value for that will be passed to the SSH connection as options (e.g., to set the password, etc.). All other options are passed to the upload! method. If a block is given, it will be used to report progress (see "Progress Reporting", under Net::SCP).
# File lib/net/scp.rb, line 219 219: def self.upload!(host, username, local, remote, options={}, &progress) 220: options = options.dup 221: start(host, username, options.delete(:ssh) || {}) do |scp| 222: scp.upload!(local, remote, options, &progress) 223: end 224: end
Starts up a new SSH connection using the host and username parameters, instantiates a new SCP session on top of it, and then begins an upload from local to remote. If the options hash includes an :ssh key, the value for that will be passed to the SSH connection as options (e.g., to set the password, etc.). All other options are passed to the upload! method. If a block is given, it will be used to report progress (see "Progress Reporting", under Net::SCP).
# File lib/net/scp.rb, line 219 219: def self.upload!(host, username, local, remote, options={}, &progress) 220: options = options.dup 221: start(host, username, options.delete(:ssh) || {}) do |scp| 222: scp.upload!(local, remote, options, &progress) 223: end 224: end
Inititiate a synchronous (non-blocking) download from remote to local. The following options are recognized:
This method will return immediately, returning the Net::SSH::Connection::Channel object that will support the download. To wait for the download to finish, you can either call the wait method on the channel, or otherwise run the Net::SSH event loop until the channel‘s active? method returns false.
channel = scp.download("/remote/path", "/local/path") channel.wait
# File lib/net/scp.rb, line 299 299: def download(remote, local, options={}, &progress) 300: start_command(:download, local, remote, options, &progress) 301: end
Inititiate a synchronous (non-blocking) download from remote to local. The following options are recognized:
This method will return immediately, returning the Net::SSH::Connection::Channel object that will support the download. To wait for the download to finish, you can either call the wait method on the channel, or otherwise run the Net::SSH event loop until the channel‘s active? method returns false.
channel = scp.download("/remote/path", "/local/path") channel.wait
# File lib/net/scp.rb, line 299 299: def download(remote, local, options={}, &progress) 300: start_command(:download, local, remote, options, &progress) 301: end
Same as download, but blocks until the download finishes. Identical to calling download and then calling the wait method on the channel object that is returned.
scp.download!("/remote/path", "/local/path")
If local is nil, and the download is not recursive (e.g., it is downloading only a single file), the file will be downloaded to an in-memory buffer and the resulting string returned.
data = download!("/remote/path")
# File lib/net/scp.rb, line 314 314: def download!(remote, local=nil, options={}, &progress) 315: destination = local ? local : StringIO.new 316: download(remote, destination, options, &progress).wait 317: local ? true : destination.string 318: end
Same as download, but blocks until the download finishes. Identical to calling download and then calling the wait method on the channel object that is returned.
scp.download!("/remote/path", "/local/path")
If local is nil, and the download is not recursive (e.g., it is downloading only a single file), the file will be downloaded to an in-memory buffer and the resulting string returned.
data = download!("/remote/path")
# File lib/net/scp.rb, line 314 314: def download!(remote, local=nil, options={}, &progress) 315: destination = local ? local : StringIO.new 316: download(remote, destination, options, &progress).wait 317: local ? true : destination.string 318: end
Inititiate a synchronous (non-blocking) upload from local to remote. The following options are recognized:
This method will return immediately, returning the Net::SSH::Connection::Channel object that will support the upload. To wait for the upload to finish, you can either call the wait method on the channel, or otherwise run the Net::SSH event loop until the channel‘s active? method returns false.
channel = scp.upload("/local/path", "/remote/path") channel.wait
# File lib/net/scp.rb, line 271 271: def upload(local, remote, options={}, &progress) 272: start_command(:upload, local, remote, options, &progress) 273: end
Inititiate a synchronous (non-blocking) upload from local to remote. The following options are recognized:
This method will return immediately, returning the Net::SSH::Connection::Channel object that will support the upload. To wait for the upload to finish, you can either call the wait method on the channel, or otherwise run the Net::SSH event loop until the channel‘s active? method returns false.
channel = scp.upload("/local/path", "/remote/path") channel.wait
# File lib/net/scp.rb, line 271 271: def upload(local, remote, options={}, &progress) 272: start_command(:upload, local, remote, options, &progress) 273: end
Same as upload, but blocks until the upload finishes. Identical to calling upload and then calling the wait method on the channel object that is returned. The return value is not defined.
# File lib/net/scp.rb, line 278 278: def upload!(local, remote, options={}, &progress) 279: upload(local, remote, options, &progress).wait 280: end
Same as upload, but blocks until the upload finishes. Identical to calling upload and then calling the wait method on the channel object that is returned. The return value is not defined.
# File lib/net/scp.rb, line 278 278: def upload!(local, remote, options={}, &progress) 279: upload(local, remote, options, &progress).wait 280: end