Как скопировать файл с одного сервера на другой?

У меня есть один сервер, который не имеет ничего, кроме файлов журнала xls. Каждый файл составляет 5-15Mb, и он динамичен в том смысле, что файлы добавляются в любой момент времени. Теперь мне нужен способ сделать следующий процесс с помощью Ruby.

  1. скопируйте файл, отправив имя файла с одного сервера, который не имеет ничего, кроме файлов журнала на другой сервер.
  2. мне нужно передать пароль сервера в качестве аргумента.
  3. все происходит в фоновом режиме, который запускается из Рубина скрипт.

4 ответов


Проверьте Net:: SCP и Net:: SSH драгоценные камни. Первый позволяет получить файл с помощью безопасной копии, а второй позволит вам легко найти имена файлов, доступных для поиска. В Net:: SSH,ssh.exec! будет твой друг.

С Net:: SCP docs:

Net:: SCP реализует протокол клиента SCP (Secure CoPy), позволяя программам Ruby безопасно и программно передавать отдельные файлы или целые деревья каталогов на удаленных серверах. Он обеспечивает поддержку нескольких одновременных копий SCP, работающих параллельно через одно и то же соединение, а также синхронных последовательных копий.

Net:: SCP также предоставляет привязку open-uri, поэтому вы можете использовать метод Kernel#open для открытия и чтения удаленного файла:

  # if you want to read from a URL voa SCP:
  require 'uri/open-scp'
  puts open("scp://user@remote.host/path/to/file").read

С Net:: SSH docs:

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:: SCP и Net:: SSH вы можете использовать Net:: SFTP, чтобы управлять всем этим в одном драгоценном камне. Он едет на безопасном соединение тоже, но SFTP может быть недоступен для вас. The Net::SFTP::Operations::Dir и Net::SFTP::Operations::Download классы и документы будут вашим другом.

другие варианты включают использование стандартных rsync в простой оболочке, как упоминалось @tadman. Существует множество способов достижения этого, и это общая потребность в средах хостинга.


любой другой лучший подход?

rsync в командной строке. Он очень умный и может перемещать папки и дельты файлов, если это необходимо. И еще:"как передавать файлы с помощью ssh и Ruby" и "Ruby файл загрузить ssh intro".

слияние @тэдман это rsync рекомендация с Ruby, есть "самая дешевая замена rsync (с Ruby)".


вот как это работает

я использовал net-ssh & net-scp gem, как предложил @theTinMan, и я смог скопировать свои файлы.

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