如何检查Capistrano中是否存在文件(在远程服务器上)?

时间:2009-11-02 14:23:11

标签: ruby file capistrano exists

与我在Googleverse中看到的许多其他人一样,我成了File.exists?陷阱的牺牲品,当然这会检查您的本地文件系统,而不是您部署到的服务器。

我发现了一个使用shell hack的结果:

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

但这并不适合我,除非它在Ruby方法中很好地包装。

有人优雅地解决了这个问题吗?

5 个答案:

答案 0 :(得分:57)

在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程序,你可以使用更简单的shell命令。

答案 1 :(得分:48)

@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 - 请查看options you can pass以获得更多控制权。

答案 2 :(得分:22)

受@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

答案 3 :(得分:5)

可能你想做的是:

isFileExist = 'if [ -d #{dir_path} ]; then echo "yes"; else echo "no"; fi'.strip
puts "File exist" if isFileExist == "yes"

答案 4 :(得分:4)

我在使用capistrano中的run命令(在远程服务器上执行shell命令)之前已经这样做了

例如,这里有一个capistrano任务,它将检查shared.configs目录中是否存在database.yml,如果存在则链接它。

  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