You want to programatically send files to another computer, the way the Unix scp command does.
Use the Net:SSH library to get a secure shell connection to the other machine. Start a cat process on the other machine, and write the file you want to copy to its standard input.
require ubygems require et/ssh def copy_file(session, source_path, destination_path=nil) destination_path ||= source_path cmd = %{cat > "#{destination_path.gsub(", \")}"} session.process.popen3(cmd) do |i, o, e| puts " Copying #{source_path} to #{destination_path}… " open(source_path) { |f| i.write(f.read) } puts Done. end end Net::SSH.start(example.com, :username=>leonardr, :password=>mypass) do |session| copy_file(session, /home/leonardr/scripts/test.rb) copy_file(session, /home/leonardr/scripts/"test".rb) end # Copying /home/leonardr/scripts/test.rb to /home/leonardr/scripts/test.rb… # Done. # Copying /home/leonardr/scripts/"test".rb to /home/leonardr/scripts/"test".rb… # Done.
The scp command basically implements the old rcp protocol over a secured connection. This code uses a shortcut to achieve the same result: it uses the high-level SSH interface to spawn a process on the remote host which writes data to a file.
Since you can run multiple processes at once over your SSH session, you can copy multiple files simultaneously. For every file you want to copy, you need to spawn a cat process:
def do_copy(session, source_path, destination_path=nil) destination_path ||= source_path cmd = %{cat > "#{destination_path.gsub(", \")}"} cat_process = session.process.open(cmd) cat_process.on_success do |p| p.write(open(source_path) { |f| f.read }) p.close puts "Copied #{source_path} to #{destination_path}." end end
The call to session.process.open creates a process-like object that runs a cat command on the remote system. The call to on_success registers a callback code block with the process. That code block will run once the cat command has been set up and is accepting standard input. Once that happens, its safe to start writing data to the file on the remote system.
Once youve set up all your copy operations, you should call session.loop to perform all the copy operations simultaneously. The processes won actually be initialized until you call session.loop.
Net::SSH.start(example.com, :username=>leonardr, :password=>mypass) do |session| do_copy(session, /home/leonardr/scripts/test.rb) do_copy(session, /home/leonardr/new_index.html, /home/leonardr/public_html/index.html) session.loop end # Copied /home/leonardr/scripts/test.rb to /home/leonardr/scripts/test.rb # Copied /home/leonardr/new_index.html to /home/leonardr/public_html/index.html
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration