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