当运行rackup作为守护进程时,File.expand_path返回/而不是项目文件夹

时间:2012-11-15 23:38:15

标签: ruby filesystems rack rackup

我不确定在某些配置文件中是否存在我做错的事情。当我运行rackup -D时,执行此操作:

File.expand_path(__FILE__)

实际上会返回/file.rb。并以某种方式添加File.dirname会返回/。所以现在我的所有文件加载代码都没有工作,因为它试图查看/目录,而不是项目目录。

如果我删除-D选项,则不会发生这种情况。它返回完整路径/home/blablabla/stuff/file.rb

示例代码:

test.rb:

require 'rubygems' if RUBY_VERSION <= '1.8.7'
require 'sinatra'

get '/expdir' do
  File.expand_path(File.dirname(__FILE__))
end

get '/exp' do
  File.expand_path(__FILE__)
end

get '/file' do
  __FILE__
end

get '/dirname' do
  File.dirname(__FILE__)
end

get '/dir' do
  Dir.entries(File.expand_path(File.dirname(__FILE__))).to_s
end

config.ru:

require 'test.rb'

run Sinatra::Application

使用rackup -p 4567执行该操作,并观察它返回正确的值。 用rackup -p 4567 -D执行它并观察它返回错误的值。

1 个答案:

答案 0 :(得分:2)

Rack确实change the working directory to / when run as a daemon

在Ruby 1.8.7中,所需文件中的__FILE__指的是用于加载文件的路径,该路径可以是来自进程当前工作目录的相对路径。但是,如果稍后更改工作目录,则该值更新,例如,致电Dir.chdir

File.expand_path扩展相对于工作目录的相对文件路径。因此,在这种情况下,File.expand_path(__FILE__)会生成相对于根的路径,但__FILE__的值相对于原始工作目录,从而产生错误的结果。

在Ruby 1.9.2和1.9.3中,所需文件中的__FILE__是指文件的绝对路径,因此不会出现此问题。

在Ruby 1.8.7中修复此问题的一种方法是在需要应用程序文件时使用绝对路径。将require 'test.rb'中的行config.ru更改为:

require File.expand_path('../test', __FILE__)

现在对__FILE__的引用是绝对的,因此在进行守护时不会受到工作目录更改的影响。

如果您的应用程序更复杂,文件更多,则最好设置加载路径。例如,您可以将所有.rb个文件放入lib/目录,然后放入config.ru添加:

$LOAD_PATH.unshift(File.expand_path '../lib', __FILE__)

然后您可以只需要您的文件而无需担心相对路径。