При запуске rackup в качестве демона File.expand_path возвращает / вместо папки проекта
Я не уверен, что я что-то не так сделал в некоторых файлах конфигурации. Когда я бегу 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 ответ
Rack действительно меняет рабочий каталог на /
когда запускается как демон.
В 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__)
Затем вы можете просто требовать свои файлы, не беспокоясь об относительных путях.