Как вы можете проверить, существует ли файл (на удаленном сервере) в Capistrano?
Как и многие другие, которые я видел в Googleverse, я стал жертвой ловушки File.exists?
, которая, конечно же, проверяет вашу локальную файловую систему, а не сервер, на который вы развертываете.
Я нашел один результат, который использовал взлом оболочки, например:
if [[ -d #{shared_path}/images ]]; then ...
но это не очень хорошо со мной, если только оно не было хорошо обернуто в Ruby-методе.
Кто-нибудь решил это элегантно?
Ответы
Ответ 1
@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
- проверьте параметры которые вы можете передать для большего контроля.
Ответ 2
В capistrano 3 вы можете:
on roles(:all) do
if test("[ -f /path/to/my/file ]")
# the file exists
else
# the file does not exist
end
end
Это хорошо, потому что он возвращает результат удаленного теста обратно в локальную рубиновую программу, и вы можете работать в более простых командах оболочки.
Ответ 3
Вдохновленный ответом @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 there!?"
end
end
desc "test existence of present file"
task :exists do
unless remote_file_exists?('/dev/null')
raise "It missing!?"
end
end
end
end
Ответ 4
Возможно, вы хотите:
isFileExist = 'if [ -d #{dir_path} ]; then echo "yes"; else echo "no"; fi'.strip
puts "File exist" if isFileExist == "yes"
Ответ 5
Я сделал это до использования команды run в capistrano (которая выполняет команду оболочки на удаленном сервере)
Например, вот одна задача capistrano, которая проверяет наличие базы данных .yml в каталоге shared/configs и связывает ее, если она существует.
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