How can you check to see if a file exists (on the remote server) in Capistrano?
Like many others I've seen in the Googleverse, I fell victim to the File.exists?
trap, which of course checks your local file system, not the server you are deploying to.
I found one resu开发者_JS百科lt that used a shell hack like:
if [[ -d #{shared_path}/images ]]; then ...
but that doesn't sit well with me, unless it were wrapped nicely in a Ruby method.
Has anybody solved this elegantly?
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
end
end
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").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
May be you want to do is:
isFileExist = 'if [ -d #{dir_path} ]; then echo "yes"; else echo "no"; fi'.strip
puts "File exist" if isFileExist == "yes"
I have done that before using the run command in capistrano (which execute a shell command on the remote server)
For example here is one capistrano task which will check if a database.yml exists in the shared/configs directory and link it if it exists.
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
精彩评论