如何将文件从一台服务器复制到另一台服务器?

我有一台服务器,只有xls日志文件。 每个文件都是5-15Mb,并且在任何时候都可以添加文件的意义上它是动态的。 现在我需要一种方法来使用Ruby来执行以下过程。

  1. 通过从一台服务器发送文件名来复制文件,该服务器只有日志文件到另一台服务器。
  2. 我需要传递服务器密码作为参数。
  3. 一切都在后台发生,这是从Ruby脚本触发的。

查看Net :: SCP和Net :: SSHgem。 第一个允许您使用安全副本检索文件,第二个允许您轻松找到可供检索的文件的名称。 在Net :: SSH中, ssh.exec! 将是你的朋友。

来自Net :: SCP文档:

Net :: SCP实现了SCP(Secure CoPy)客户端协议,允许Ruby程序安全地以编程方式将单个文件或整个目录树传输到远程服务器或从远程服务器传输。 它支持在同一连接上并行工作的多个同时SCP副本,以及同步,串行副本。

Net :: SCP还提供了open-uri绑定,因此您可以使用Kernel#open方法打开并读取远程文件:

   #如果你想从URL voa SCP中读取:
  要求'uri / open-scp'
   put open(“scp://user@remote.host/path/to/file”)。read

来自Net :: SSH文档:

 require 'net/ssh' Net::SSH.start('host', 'user', :password => "password") do |ssh| # capture all stderr and stdout output from a remote process output = ssh.exec!("hostname") 

在上面的代码中添加一个end以关闭该块。 在块内, output将包含您发送的命令的结果。

从包含文件的机器通过Ruby检索文件的替代方法是让Ruby直接从托管文件的机器启动传输,并通过scp将它们推送到另一台机器。

您可以使用Net :: SFTP在一个gem中管理它,而不是使用Net :: SCP和Net :: SSH。 它也依赖于安全连接,但您可能无法使用SFTP。 Net::SFTP::Operations::DirNet::SFTP::Operations::Download类和文档将成为您的朋友。

其他选项包括在@tadman提到的简单shell中使用标准rsync 。 有许多方法可以实现这一点,这是托管环境中的常见需求。


任何其他更好的方法?

rsync ,在命令行。 它非常智能,可以根据需要移动文件夹和文件的增量。 另外,“ 如何使用ssh和Ruby传输文件 ”及其链接到“ Ruby file upload ssh intro ”。

Melding @ tadman对Ruby的rsync建议,有“ 最便宜的rsync替换(使用Ruby) ”。

这就是它的工作原理

我使用了@theTinMan建议的net-ssh和net-scp gem,我能够复制我的文件。

 require 'rubygems' require 'net/ssh' require 'net/scp' Net::SSH.start("ip_address", "username",:password => "*********") do |session| session.scp.download! "/home/logfiles/2-1-2012/login.xls", "/home/anil/Downloads" end 

并复制整个文件夹

 require 'rubygems' require 'net/ssh' require 'net/scp' Net::SSH.start("ip_address", "username",:password => "*********") do |session| session.scp.download!("/home/logfiles/2-1-2012", "/home/anil/Downloads", :recursive => true) end 

您应该只使用rsync而不是滚动自己的东西。 使用带公钥/私钥访问的ssh ,您将避免使用密码。 完全使用密码可能是一个坏主意。

似乎没有scp是可能的

 @session = Net::SSH.start(@ftpIp, @ftpUser, :password => @ftpPass) @conn = Net::SFTP::Session.new(@session).connect! def download_remote_folder(remote_path, local_path, use_ssh = @use_ssh) @conn ||= connect if (use_ssh) @conn.download!(remote_path,local_path,:recursive => true) else @conn.get(remote_path, local_path) end end def download_remote_file(remote_path, local_path, use_ssh = @use_ssh) @conn ||= connect if (use_ssh) @conn.download!(remote_path,local_path) else @conn.get_file(remote_path, local_path) end end