与我在Googleverse中看到的许多其他人一样,我成了File.exists?
陷阱的牺牲品,当然这会检查您的本地文件系统,而不是您部署到的服务器。
我发现了一个使用shell hack的结果:
if [[ -d #{shared_path}/images ]]; then ...
但这并不适合我,除非它在Ruby方法中很好地包装。
有人优雅地解决了这个问题吗?
答案 0 :(得分:57)
在capistrano 3中,你可以这样做:
on roles(:all) do
if test("[ -f /path/to/my/file ]")
# the file exists
else
# the file does not exist
end
end
这很好,因为它将远程测试的结果返回给本地ruby程序,你可以使用更简单的shell命令。
答案 1 :(得分:48)
@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
- 请查看options you can pass以获得更多控制权。
答案 2 :(得分:22)
受@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'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
答案 3 :(得分:5)
可能你想做的是:
isFileExist = 'if [ -d #{dir_path} ]; then echo "yes"; else echo "no"; fi'.strip
puts "File exist" if isFileExist == "yes"
答案 4 :(得分:4)
我在使用capistrano中的run命令(在远程服务器上执行shell命令)之前已经这样做了
例如,这里有一个capistrano任务,它将检查shared.configs目录中是否存在database.yml,如果存在则链接它。
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