Как проверить, существует ли файл (на удаленном сервере) в Capistrano? - PullRequest
41 голосов
/ 02 ноября 2009

Как и многие другие, которых я видел в Googleverse, я стал жертвой ловушки File.exists?, которая, конечно, проверяет вашу локальную файловую систему, а не сервер, на котором вы развертываете.

Я нашел один результат, который использовал взлом оболочки, как:

if [[ -d #{shared_path}/images ]]; then ...

но это меня не устраивает, если только оно не было красиво упаковано в метод Ruby.

Кто-нибудь решил это элегантно?

Ответы [ 5 ]

57 голосов
/ 02 января 2014

В Capistrano 3 вы можете сделать:

on roles(:all) do
  if test("[ -f /path/to/my/file ]")
    # the file exists
  else
    # the file does not exist
  end
end

Это хорошо, потому что он возвращает результат удаленного теста обратно в вашу локальную программу ruby, и вы можете работать с более простыми командами оболочки.

48 голосов
/ 15 марта 2013

@ knocte правильно, что capture проблематично, потому что обычно все нацелены на развертывание более чем на один хост (а захват получает только выходные данные с первого) Чтобы проверить все хосты, вам нужно использовать invoke_command (это то, что capture использует внутри). Вот пример, в котором я проверяю, существует ли файл на всех соответствующих серверах:

def remote_file_exists?(path)
  results = []

  invoke_command("if [ -e '#{path}' ]; then echo -n 'true'; fi") do |ch, stream, out|
    results << (out == 'true')
  end

  results.all?
end

Обратите внимание, что invoke_command по умолчанию использует run - проверьте параметры , которые вы можете передать для большего контроля.

22 голосов
/ 02 ноября 2009

Вдохновленный ответом @bhups, с тестами:

def remote_file_exists?(full_path)
  'true' ==  capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
end

namespace :remote do
  namespace :file do
    desc "test existence of missing file"
    task :missing do
      if remote_file_exists?('/dev/mull')
        raise "It's there!?"
      end
    end

    desc "test existence of present file"
    task :exists do
      unless remote_file_exists?('/dev/null')
        raise "It's missing!?"
      end
    end
  end
end
5 голосов
/ 02 ноября 2009

Может быть, вы хотите сделать это:

isFileExist = 'if [ -d #{dir_path} ]; then echo "yes"; else echo "no"; fi'.strip
puts "File exist" if isFileExist == "yes"
4 голосов
/ 03 ноября 2009

Я сделал это перед использованием команды запуска в capistrano (которая выполняет команду оболочки на удаленном сервере)

Например, вот одна задача capistrano, которая проверит, существует ли database.yml в каталоге shared / configs, и свяжет его, если он существует.

  desc "link shared database.yml"
  task :link_shared_database_config do
    run "test -f #{shared_path}/configs/database.yml && ln -sf 
    #{shared_path}/configs/database.yml #{current_path}/config/database.yml || 
    echo 'no database.yml in shared/configs'"
  end
...