在 Capistrano 任务中检查目录是否存在失败
Checking directory existence in Capistrano task fails
我在服务器上添加了新硬盘,需要用它来保存所有用户信息,所以我需要将public目录移动到新硬盘。
我不知道在我的情况下什么是最好的方法,但我决定将 public 目录更改为 符号 link 指向到新的硬盘路径。
基于此,我在部署后创建了以下 capistrano task
到 运行:
# I'm using capistrano 3.1
namespace :public_to_symbolic do
desc 'Change public directory to symbolic link pointing to other Hdd'
task :change do
on roles(:app) do
is_directory = File.directory?("#{release_path}/public")
is_symbolic_link = File.symlink?("#{release_path}/public")
is_new_directory_exist = File.directory?('/mnt/newhdd/public')
can_change = is_directory && !is_symbolic_link && is_new_directory_exist
puts "is_directory : #{is_directory}" # prints false
puts "is_symbolic_link : #{is_symbolic_link}" # prints false
puts "is_new_directory_exist : #{is_new_directory_exist}" # prints false
puts "can_change: #{can_change}" # prints false
puts "release_path: #{release_path}" # prints /var/www/myapp/releases/20180305112922
if can_change
puts 'Changing public directory to symbolic link'
execute "mv #{release_path}/public #{release_path}/public_linked"
execute "ln -s /mnt/newhdd/public #{release_path}/public"
execute "rm -rf #{release_path}/public_linked"
end
end
end
end
after 'deploy', 'public_to_symbolic:change'
因此,如评论所述,is_directory
、is_symbolic_link
和 is_new_directory_exist
都是 returns false
,但是当我进行相同的检查时(即 File.directory?("#{Rails.root}/public")
或 File.directory?("/var/www/myapp/current/public")
) 在部署服务器上使用 Rails 控制台,我得到 true
并且我能够看到 public 目录!
为了避免这个问题,我也尝试使用 current_path
而不是 release_path
,但结果仍然相同。
我有两个问题:
- 为什么
is_directory
和 is_new_directory_exist
总是 false
而任务是 运行ning?
- 如果有更好的方法在不同硬盘上使用public目录,请指教。
欢迎所有建议
您在 local 机器上的 Capistrano 任务 运行 中使用的所有 Ruby 方法。
例如:
File.directory?
File.symlink?
这些总是在您的本地文件系统上进行评估。 Capistrano 从不在远程服务器上 运行s Ruby 代码。这些方法总是 return false
适合你,因为它们试图找到例如"#{release_path}/public"
在您的本地计算机上,这当然不存在。
到服务器上的运行代码,你可以使用的工具是Capistrano的test
和execute
方法。这些接收通过 SSH 远程执行的命令字符串。
如果要测试远程路径是否为目录,则不能使用Ruby;你必须在远程 shell 中使用可以 运行 的东西。下面是一种测试路径是否为目录的方法,例如:
is_directory = test("[ -d #{release_path}/public ]")
同样,测试路径是否为符号链接:
is_symbolic_link = test("[ -h #{release_path}/public ]")
我在服务器上添加了新硬盘,需要用它来保存所有用户信息,所以我需要将public目录移动到新硬盘。
我不知道在我的情况下什么是最好的方法,但我决定将 public 目录更改为 符号 link 指向到新的硬盘路径。
基于此,我在部署后创建了以下 capistrano task
到 运行:
# I'm using capistrano 3.1
namespace :public_to_symbolic do
desc 'Change public directory to symbolic link pointing to other Hdd'
task :change do
on roles(:app) do
is_directory = File.directory?("#{release_path}/public")
is_symbolic_link = File.symlink?("#{release_path}/public")
is_new_directory_exist = File.directory?('/mnt/newhdd/public')
can_change = is_directory && !is_symbolic_link && is_new_directory_exist
puts "is_directory : #{is_directory}" # prints false
puts "is_symbolic_link : #{is_symbolic_link}" # prints false
puts "is_new_directory_exist : #{is_new_directory_exist}" # prints false
puts "can_change: #{can_change}" # prints false
puts "release_path: #{release_path}" # prints /var/www/myapp/releases/20180305112922
if can_change
puts 'Changing public directory to symbolic link'
execute "mv #{release_path}/public #{release_path}/public_linked"
execute "ln -s /mnt/newhdd/public #{release_path}/public"
execute "rm -rf #{release_path}/public_linked"
end
end
end
end
after 'deploy', 'public_to_symbolic:change'
因此,如评论所述,is_directory
、is_symbolic_link
和 is_new_directory_exist
都是 returns false
,但是当我进行相同的检查时(即 File.directory?("#{Rails.root}/public")
或 File.directory?("/var/www/myapp/current/public")
) 在部署服务器上使用 Rails 控制台,我得到 true
并且我能够看到 public 目录!
为了避免这个问题,我也尝试使用 current_path
而不是 release_path
,但结果仍然相同。
我有两个问题:
- 为什么
is_directory
和is_new_directory_exist
总是false
而任务是 运行ning? - 如果有更好的方法在不同硬盘上使用public目录,请指教。
欢迎所有建议
您在 local 机器上的 Capistrano 任务 运行 中使用的所有 Ruby 方法。
例如:
File.directory?
File.symlink?
这些总是在您的本地文件系统上进行评估。 Capistrano 从不在远程服务器上 运行s Ruby 代码。这些方法总是 return false
适合你,因为它们试图找到例如"#{release_path}/public"
在您的本地计算机上,这当然不存在。
到服务器上的运行代码,你可以使用的工具是Capistrano的test
和execute
方法。这些接收通过 SSH 远程执行的命令字符串。
如果要测试远程路径是否为目录,则不能使用Ruby;你必须在远程 shell 中使用可以 运行 的东西。下面是一种测试路径是否为目录的方法,例如:
is_directory = test("[ -d #{release_path}/public ]")
同样,测试路径是否为符号链接:
is_symbolic_link = test("[ -h #{release_path}/public ]")