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

前端 未结 5 864
忘了有多久
忘了有多久 2020-12-24 01:14

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 y

相关标签:
5条回答
  • 2020-12-24 01:45

    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
    
    0 讨论(0)
  • 2020-12-24 01:50

    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.

    0 讨论(0)
  • 2020-12-24 01:50

    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"
    
    0 讨论(0)
  • 2020-12-24 02:00

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

    0 讨论(0)
  • 2020-12-24 02:03

    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
    
    0 讨论(0)
提交回复
热议问题