How can you check to see if a file exists (on the remote server) in Capistrano? How can you check to see if a file exists (on the remote server) in Capistrano? ruby ruby

How can you check to see if a file exists (on the remote server) in Capistrano?


In capistrano 3, you can do:

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

This is nice because it returns the result of the remote test back to your local ruby program and you can work in simpler shell commands.


@knocte is correct that capture is problematic because normally everyone targets deployments to more than one host (and capture only gets the output from the first one). In order to check across all hosts, you'll need to use invoke_command instead (which is what capture uses internally). Here is an example where I check to ensure a file exists across all matched servers:

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

Note that invoke_command uses run by default -- check out the options you can pass for more control.


Inspired by @bhups response, with tests:

def remote_file_exists?(full_path)  'true' ==  capture("if [ -e #{full_path} ]; then echo 'true'; fi").stripendnamespace :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  endend